Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Datei kopieren mit Fortschrittsanzeige (https://www.delphipraxis.net/16354-datei-kopieren-mit-fortschrittsanzeige.html)

changlee 20. Aug 2019 07:15

AW: Datei kopieren mit Fortschrittsanzeige
 
Zitat:

Zitat von tomkupitz (Beitrag 1442147)
Windows.CopyFileEx geht auch...

...ermöglicht aber leider keine Fortschrittsanzeige.


Zu den Hinweisen von Luckie und Dalai, habe ich ein paar Tests gemacht.

Das Problem tritt auf beim Schreiben auf externe HDDs (schreibend auf USB2.0/USB3.0, lesend von USB2.0/USB3.0/interne SSD).
Das Problem tritt nicht auf beim Schreiben auf die interne SSD (schreibend auf interne SSD, lesend von USB2.0/USB3.0/interne SSD).-> liegt also offenbar nicht am Virenscanner

Leider habe ich keine externe SSD und keine interne HDD zum Testen.

Die Zeit für Closefile beträgt nach groben Abschätzen bei den Versuchen ca. ein Drittel der Kopierdauer für die ganze Datei - sofern auf eine HDD geschrieben wird.
Bei einer SSD benötigt Closefile keine spürbare Zeit, selbst bei sehr großen Dateien nicht.

Fallen euch noch irgendwelche Ansatzpunkte ein?

dummzeuch 20. Aug 2019 08:09

AW: Datei kopieren mit Fortschrittsanzeige
 
Zitat:

Zitat von changlee (Beitrag 1442190)
Zitat:

Zitat von tomkupitz (Beitrag 1442147)
Windows.CopyFileEx geht auch...

...ermöglicht aber leider keine Fortschrittsanzeige.

Doch, es erlaubt genau das:

CopyFileWithProgress (using CopyFileEx)

Benutze ich schon seit Jahren problemlos.

changlee 20. Aug 2019 18:42

AW: Datei kopieren mit Fortschrittsanzeige
 
ok danke. Das hatte ich anders in Erinnerung.
Ich will es gerade testen, habe aber noch ein Problem mit dem Aufruf von CopyFileEx.
Der Beispielcode ist mir zugegebener Maßen zu umfangreich. Ich versuche ein Minimalbeispiel umzusetzen:

Code:
function TJobThread.SyncProgress2(_TotalFileSize, _TotalBytesTransferred, _StreamSize, _StreamBytesTransferred: LARGE_INTEGER; _StreamNumber, _CallbackReason: LongWord; _SourceFile, _DestinationFile: THandle; _Data: Pointer): LongWord;
begin
  // mach irgendwas..
end;

procedure TJobThread.Execute;
var
  src1,tgt:string;
begin
    src := 'c:\temp\datei1.img';
    tgt := 'c:\temp\datei2.img';
    Windows.CopyFileEx(PChar(src), PChar(tgt), SyncProgress2, Redir, @Redir.FCancelFlag, Flags); // Fehler beim Compilieren: E2035 Nicht genügend wirkliche Parameter
    Windows.CopyFileEx(PChar(src), PChar(tgt), @SyncProgress2, Redir, @Redir.FCancelFlag, Flags); // Fehler beim Compilieren: E2036 Variable erforderlich
end;
Wie kann ich die Funktion SyncProgress2 übergeben?


Falls noch jemand eine Idee hat warum closfile bzw. Stream.Free so lange dauert, bin ich aber auch da noch für jeden Tip dankbar.

Forensiker 20. Aug 2019 18:58

AW: Datei kopieren mit Fortschrittsanzeige
 
SyncProgress2 ist eine callback und sollte Global definiert sein.. nicht innerhalb einer Klasse.
Delphi-Quellcode:
Windows.CopyFileEx(PChar(src), PChar(tgt), SyncProgress2, Redir, @Redir.FCancelFlag, Flags); // Fehler beim Compilieren: E2035 Nicht genügend wirkliche Parameter

Kann nicht funktionieren da ein Pointer auf die Callback erwartet wird.
Delphi-Quellcode:
Windows.CopyFileEx(PChar(src), PChar(tgt), @SyncProgress2, Redir, @Redir.FCancelFlag, Flags); // Fehler beim Compilieren: E2036 Variable erforderlich

Siehe erste Zeile im Beitrag.

changlee 20. Aug 2019 19:40

AW: Datei kopieren mit Fortschrittsanzeige
 
ich hab's befürchtet. Ich kann wirklich keine Klassenmethode übergeben??

Dann kapiere ich es aber immer noch nicht.
Ich habe jezt folgenden Code:

Code:
procedure TJobThread.SyncProgress(Position, Size: int64);
begin
  self.fProgressPosition := Position;
  self.fProgressSize     := Size;
  self.fProgressToPublish := 0;
  self.Synchronize(self.publishProgress);
end;

function SyncProgress2(_TotalFileSize, _TotalBytesTransferred, _StreamSize, _StreamBytesTransferred: LARGE_INTEGER; _StreamNumber, _CallbackReason: LongWord; _SourceFile, _DestinationFile: THandle; _Data: Pointer): LongWord;
var a,b:int64;
begin
  //a := int64(_TotalBytesTransferred);
  //b := int64(_TotalFileSize);
  //TJobThread(_Data).SyncProgress(a,b);
  result := PROGRESS_CONTINUE;
end;


procedure TJobThread.Execute;
var
  doCancel : PBOOL;
  src,tgt:string;
begin
  src := 'c:\temp\datei1.img';
  tgt := 'c:\temp\datei2.img';
  doCancel := PBOOL(False);
  Windows.CopyFileEx(PChar(s1), PChar(s2), @SyncProgress2, @self, doCancel, 0) then begin
end;
Die Zieldatei wird erstellt, enthält aber keine Daten. Der Kopiervorgang ist sofort zu Ende und die Datei nicht zu öffnen.
Setze ich einen Haltepunkt bekomme ich beim Aufruf von CopyFileEx eine Zugriffsverletzung (Lesen von Adresse...).

Luckie 20. Aug 2019 20:08

AW: Datei kopieren mit Fortschrittsanzeige
 
http://michael-puff.de/Programmierun...pyFileEx.shtml

changlee 20. Aug 2019 20:35

AW: Datei kopieren mit Fortschrittsanzeige
 
Den Code hatte ich auch schon gefunden ;-)

Aber trotzdem gut, dass du ihn nochmal geschickt hast.
Ich habe meine beiden Fehler gefunden:

Code:
function SyncProgress2(...): LongWord; // ALT, Kopiervorgang schlägt fehl
function SyncProgress2(...): DWORD; stdcall; // NEU, Kopiervorgang funktionert
...
TJobThread(_Data).SyncProgress(a,b); // Falsch
TJobThread(_Data^).SyncProgress(a,b); // Korrekt
Danke!!!

Viele Grüße
Stefan

Luckie 20. Aug 2019 23:13

AW: Datei kopieren mit Fortschrittsanzeige
 
Ok, dann findet man die Quellcodes auf meiner Seite also noch. ;-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:27 Uhr.
Seite 3 von 3     123   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz