Hallo zusammen,
ich versuche verzweifelt, größere Dateien (200 MB und größer) von einem Windows-Rechner auf einen Mac zu kopieren, indem ich die WriteFile-Funktion verwende. Das Problem ist, dass z.B. beim WriteFile -1 zurückgegeben wird, nachdem einige Blöcke geschrieben wurden. RaiseLastOSError gibt 112 zurück, es ist aber ausreichend Speicherplatz vorhanden.
Wenn ich denselben Block mit WriteFile wieder und wieder versuche zu schreiben, klappt es nach einigen Versuchen (ca. 20-40).
Kopiere ich die Datei mit dem Windows Explorer (bzw. ShFileOperation), dann funktionert es. Ist in meinem Fall aber keine Alternative, ich möchte das mit WriteFile gelöst bekommen.
Das Problem lässt sich mit jedem beliebigen Mac reproduzieren. Einfach größere Dateien über's Netzwerk vom PC auf einen Mac per WriteFile kopieren - die Puffergröße scheint nicht relevant zu sein (in meinem Fall 64 KB).
Hat da jemand eine Idee? Mir ist völlig unklar, was da genau die Ursache sein soll.
Viele Grüße
Andy
Moderiert von Narses: Beiträge zusammengefasstAnbei mal eine Beispielfunktion, die ich zum Testen geschrieben habe:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69:
| function GetFileSizeBytes(Filename: String): Int64; var SRec: TSearchRec; Found: Integer; begin try Found := FindFirst(Filename, faAnyFile, SRec); if Found = 0 then Result := SRec.Size else Result := -1; finally FindClose(SRec); end; end;
function SynchronizeFile(Source, Destination: String): Boolean; var NumRead, NumWritten: Integer; ReadFileHandle, WriteFileHandle: THandle; DestinationExists, Hashing: Boolean; Buffer: Array of char; FileLength: Int64; begin result := false; SetLength(Buffer, (64 * 1024) - 1);
ReadFileHandle := FileOpen(Source, fmOpenRead or fmShareDenyNone); if ReadFileHandle = INVALID_HANDLE_VALUE then exit;
try FileLength := GetFileSizeBytes(Source); Application.ProcessMessages; if not DirectoryExists(ExtractFilePath(Destination)) then ForceDirectories(ExtractFilePath(Destination));
WriteFileHandle := FileCreate(Destination); if WriteFileHandle = INVALID_HANDLE_VALUE then exit;
with Form1.ProgressBar1 do begin Min := 0; Max := (FileLength div ((64 * 1024) - 1)); Position := 0; repeat NumRead := FileRead(ReadFileHandle, Buffer[0], (64 * 1024) - 1); if NumRead > 0 then begin NumWritten := FileWrite(WriteFileHandle, Buffer[0], NumRead); if NumWritten <> NumRead then begin ShowMessage('Failed'); exit; end; end; Position := Position + 1; Application.ProcessMessages; until (NumRead <= 0); if NumRead = -1 then begin ShowMessage('Failed'); exit; end;
result := true; end; finally FileClose(ReadFileHandle); FileClose(WriteFileHandle); end; end; |
Moderiert von Narses: Beiträge zusammengefasstIch nochmal.
Damit es auf dem Mac auch funktioniert, muss ich die Datei mit FileCreate erstellen, schließen und mit FileOpen im Schreibmodus (fmOpenWrite) wieder öffnen. Oder eben direkt mit CreateFile im Schreibmodus erstellen/öffnen.