Ich habe mit eine eigene Kopierroutine geschrieben. Grund dafür ist, das der CopyFile-Befehl zu "unflexibel" ist und kein Progress unterstützt. Leider ist mir nachdem ich die Procs schon einige Zeit nutze nun aufgefallen, das offensichtlich bei einer bestimmten Dateigröße es Probleme gibt.
Unzählige Dateien funktionieren perfekt. Aber eine Testdatei wird nicht komplett geschrieben.
Jemand eine Idee?
Hier der Code:
Code: Alles auswählen
EnableExplicit
Procedure SK_CopyFile(sourcefile$, targetfile$, OverwriteExistingFile.b=#True, *ProgressRoutine.l=0, fPackSize.f=0)
; Definitionen
Define.f fSourceFileLen, fSourceFilePos, fPackSize
Define.l lSourceFile, lTargetFile, result
Define.l Memory.MEMORYSTATUS
Define.f *CopyBuffer, DataReaded
Define.b bGlobalAbort, UTC_Korrektur
; Rückgabe-Codes definieren
#SK_CopyFile_Failed = 0 ; #False
#SK_CopyFile_OK = 1 ; #True
#SK_CopyFile_0ByteFile = 2 ; Quell-Datei ist 0 Byte groß
#SK_CopyFile_UserAbort = -1 ; User hat abgebrochen
#SK_CopyFile_FileNotFound = -2 ; Quell-Datei nicht gefunden
#SK_CopyFile_CannotOpenSource = -3 ; Konnte Quelle nicht öffnen
#SK_CopyFile_CannotCreateTarget = -4 ; Konnte Zieldatei nicht anlegen
#SK_CopyFile_TargetCorrupt = -5 ; Source-Size und Target-Size sind unterschiedlich. Ggf, Speicher voll.
#SK_CopyFile_MemoryError = -6 ; Konnte Speicher nicht reservieren
; Standard-Wert für Rückgabe: Fehler!
result=#SK_CopyFile_Failed
; Progress-Routine (Aufbaubeispiel)
; Procedure SK_CopyFile_ProgressCallback(act_pos, filesize)
; If filesize>0
; percentage_done = (act_pos*100)/filesize
; Else
; percentage_done = 100
; EndIf
; SetGadgetState(#main_progressbar_file, percentage_done)
; EndProcedure
; Gibt es Zieldatei schon: User fragen wie es weiter gehen soll!
If FileSize(targetfile$)>0 And OverwriteExistingFile=#False ; Ziel existiert, User will gefragt werden!
If MessageRequester("","Möchten Sie folgende Datei überschreiben?"+#CRLF$+#CRLF$+targetfile$, #PB_MessageRequester_YesNo) = #PB_MessageRequester_No
ProcedureReturn #SK_CopyFile_UserAbort
EndIf
EndIf
; Quelle öffnen
lSourceFile = ReadFile(#PB_Any, sourcefile$)
fSourceFilePos.f = 0
If lSourceFile ; Quelle öffnen ok?
; Zieldatei erzeugen
lTargetFile = CreateFile(#PB_Any, targetfile$)
If lTargetFile ; Ziel öffnen ok?
; Wieviel arbeit liegt vor uns
fSourceFileLen.f=Lof(lSourceFile) ; Dateigröße ermitteln
If fSourceFileLen > 0 ; Quelle eine 0-Byte-Datei?
; Paketgröße ermitteln
If fPackSize = 0 ; Dynamische Paketgröße
GlobalMemoryStatus_(Memory.MEMORYSTATUS)
If fSourceFileLen < 3145728 ; 3 MB
fPackSize = fSourceFileLen
ElseIf (fSourceFileLen/100) < (Memory\dwAvailPhys / 4)
fPackSize = fSourceFileLen / 100
Else
fPackSize = (Memory\dwAvailPhys / 1000)
EndIf
EndIf
; Falls ProgressCallback: Startwert eintragen, damit User sieht es passiert was
If *ProgressRoutine <> 0
CallFunctionFast(*ProgressRoutine, 1, fSourceFileLen)
EndIf
; Speicher reservieren für Blocks...
*CopyBuffer = AllocateMemory(fPackSize)
If *CopyBuffer ; Speicher ok? Dann los!
Repeat
; Haben wir einen Rest zu kopieren?
If fSourceFilePos+fPackSize > fSourceFileLen
fPackSize = fSourceFileLen-fSourceFilePos ; Restdaten ermitteln
If fPackSize>0 ; Nur Speicher reservieren, wenn ein Rest vorhanden
*CopyBuffer = ReAllocateMemory(*CopyBuffer, fPackSize)
Else ; Kein Rest -> raus hier, da stimmt was nicht
result = #SK_CopyFile_Failed
Break
EndIf
EndIf
; Daten aus Quelle einlesen
DataReaded = ReadData(lSourceFile, *CopyBuffer, fPackSize)
If DataReaded > 0 ; Daten korrekt gelesen? Dann ab in die Zieldatei
WriteData(lTargetFile, *CopyBuffer, DataReaded)
fSourceFilePos + DataReaded
ElseIf DataReaded = 0 And fSourceFilePos < fSourceFileLen ; Ui, da ging was schief
result = #SK_CopyFile_Failed
;Break
EndIf
; Progress aktualisieren
If *ProgressRoutine <> 0 And DataReaded > 0
CallFunctionFast(*ProgressRoutine, fSourceFilePos, fSourceFileLen)
EndIf
Until fSourceFilePos >= fSourceFileLen Or DataReaded=0 Or bGlobalAbort=#True
; NUR FÜR TEST
Debug "FINISHED"
Debug DataReaded
Debug fSourceFilePos
Debug fSourceFileLen
If bGlobalAbort = #True ; Hat User abgebrochen?
result = #SK_CopyFile_UserAbort
EndIf
If fSourceFileLen <> fSourceFilePos ; Gibts Probleme mit den Dateigrößen? Differenzen?
result = #SK_CopyFile_TargetCorrupt
Debug "Source <> Target"
EndIf
; Speicher wieder freigeben!
FreeMemory(*CopyBuffer)
Else
result = #SK_CopyFile_MemoryError ; Probleme beim Speicher reservieren
EndIf
Else
result = #SK_CopyFile_0ByteFile ; War ne 0-Byte-Datei
EndIf
; Zieldatei wieder schließen
CloseFile(lTargetFile)
Else
result = #SK_CopyFile_CannotCreateTarget ; Zieldatei konnte nicht angelegt werden
EndIf
; Quelldatei wieder schließen
CloseFile(lSourceFile)
; Datum und Attribute wie Originaldatei setzen
SetFileDate(targetfile$, #PB_Date_Created, AddDate(GetFileDate(sourcefile$, #PB_Date_Created), #PB_Date_Hour, UTC_Korrektur))
SetFileDate(targetfile$, #PB_Date_Modified, AddDate(GetFileDate(sourcefile$, #PB_Date_Modified), #PB_Date_Hour, UTC_Korrektur) )
SetFileAttributes(targetfile$, GetFileAttributes(sourcefile$)) ; Attribute angleichen
; Progress lieber nochmal auf 100% setzen
If *ProgressRoutine <> 0
CallFunctionFast(*ProgressRoutine, fSourceFileLen, fSourceFileLen)
EndIf
result = #SK_CopyFile_OK ; Super, alles ok
Else
result = #SK_CopyFile_CannotOpenSource ; Quelle konnte nicht geöffnet werden :(
EndIf
ProcedureReturn result
EndProcedure
; TESTLAUF
; Probleme mit einer Datei festgestellt. Quell-Dateigröße: 60366336 Bytes. Ziel nach Copy: 60366265 ????
; Duzende anderen Datein funktionieren. Liegts an der Dateigröße???
Define.s testfile$
testfile$ = "CaromV482.exe"
;testfile$ = "ReactOS-LiveCD.iso"
Debug SK_CopyFile("D:\1\"+testfile$, "D:\2\"+testfile$)
Debug FileSize("D:\1\"+testfile$)
Debug FileSize("D:\2\"+testfile$)
SetClipboardText(Str(FileSize("D:\2\"+testfile$)))
Vielen Dank im vorraus.
