Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Systemfehlercode 6 beim Kopieren von Dateien (https://www.delphipraxis.net/202413-systemfehlercode-6-beim-kopieren-von-dateien.html)

DieDolly 31. Okt 2019 12:49

Systemfehlercode 6 beim Kopieren von Dateien
 
Ab und zu kommt es vor, dass mir Systemfehlercode 6 beim Kopieren von Dateien angezeigt wird.
Die Windows-Hilfe sagt dazu nur Invalid Handle.

Was genau soll man mit der Meldung anfangen und warum tritt die auf, wenn die Quelldatei existiert?

peterbelow 31. Okt 2019 14:01

AW: Systemfehlercode 6 beim Kopieren von Dateien
 
Zitat:

Zitat von DieDolly (Beitrag 1450594)
Ab und zu kommt es vor, dass mir Systemfehlercode 6 beim Kopieren von Dateien angezeigt wird.
Die Windows-Hilfe sagt dazu nur Invalid Handle.

Was genau soll man mit der Meldung anfangen und warum tritt die auf, wenn die Quelldatei existiert?

Wie kopierst Du die Datei? Wo liegt sie (lokale platte, netzlaufwerk?

DieDolly 31. Okt 2019 15:21

AW: Systemfehlercode 6 beim Kopieren von Dateien
 
Wenn der Fehler auftritt, dann bei allen Kombinationen von Datenträgern.
Hier in dem Fall aber von einer externen Festplatte zur anderen. Ich kopiere Dateien klassisch mit ReadFile und WriteFile blockweise. Der Fehler tritt sporadisch auf.

Luckie 31. Okt 2019 16:10

AW: Systemfehlercode 6 beim Kopieren von Dateien
 
Zeig mal den Code.

peterbelow 1. Nov 2019 16:59

AW: Systemfehlercode 6 beim Kopieren von Dateien
 
Zitat:

Zitat von DieDolly (Beitrag 1450611)
Wenn der Fehler auftritt, dann bei allen Kombinationen von Datenträgern.
Hier in dem Fall aber von einer externen Festplatte zur anderen. Ich kopiere Dateien klassisch mit ReadFile und WriteFile blockweise. Der Fehler tritt sporadisch auf.

Verwende doch einfach Copyfile /Sysutils unit, oder TFile.Copy (IOUtils unit)

DieDolly 1. Nov 2019 17:12

AW: Systemfehlercode 6 beim Kopieren von Dateien
 
Es ist eine Kopie von hier umgeschrieben zu 64bit https://stackoverflow.com/questions/...fast-file-copy
Ich nutze diese Funktion statt TFile.Copy weil ich der Meinung bin mehr Kontrolle zu haben.

Wie benutzt man TFile.Copy richtig, um auch auf Abbruchereignisse zu reagieren?

Ich habs mal so versucht aber das mit dem CallBack funktioniert nicht so richtig. Ich würde gerne auf die Variable die Anzahl Bytes hinzuaddieren, die pro Durchlauf dazukommen
Mit der Funktion oben kopiere ich immer in 50MB-Schritten und kann so auch immer schön 50MB auf die Variable hinzuaddieren.
Delphi-Quellcode:
Winapi.Windows.CopyFileEx(PWideChar(Source), PWideChar(Dest), @CopyCallback, nil, @Cancel, 0);

function CopyCallback(TotalFileSize, TotalBytesCopied, StreamSize, StreamBytesTransferred: Int64; dwStreamNumber, dwCallbackReason: DWORD; hSourceFile, hDestinationFile: THandle)
 : DWORD; stdcall;
var
 CanContinue: Boolean;
const
 PROCESS_CONTINUE = 0;
begin
 CanContinue := not Cancel;

 Result := PROCESS_CONTINUE;
 if dwCallbackReason = CALLBACK_CHUNK_FINISHED then
  begin
   if CanContinue then
    begin
     // Auf die Variable BytesCopied möchte ich hinzuaddieren, wieviele Bytes pro Durchlauf kopiert wurden
    end;
  end;
end;
Eine Idee wäre,
Delphi-Quellcode:
BytesCopiedTemp := BytesCopied - StreamBytesTransferred;
. In BytesCopiedTemp steht in meinem Fall jetzt durchgehend 1 MB, den ich auf BytesCopied hinzuaddieren kann. Aber so richtig scheint das bei mehreren Dateien auch nicht zu funktionieren, denn BytesCopied geht bei jeder Datei auf 0 zurück wenn mehr als eine Datei kopiert werden soll.
Delphi-Quellcode:
   if CanContinue then
    begin
     BytesCopiedTmp := BytesCopied - StreamBytesTransferred;
     Inc(BytesCopied, BytesCopiedTmp);
    end;
Kann mir da jemand helfen? Auf BytesCopied möchte ich immer die Größe des aktuell kopierten Chunks addieren. Aber 2 Dateien ist BytesCopiedTmp aber so groß wie ein PB und spinnt kurz herum.

p80286 2. Nov 2019 08:44

AW: Systemfehlercode 6 beim Kopieren von Dateien
 
Zitat:

Zitat von DieDolly (Beitrag 1450642)

Eine Idee wäre,
Delphi-Quellcode:
BytesCopiedTemp := BytesCopied - StreamBytesTransferred;
. In BytesCopiedTemp steht in meinem Fall jetzt durchgehend 1 MB, den ich auf BytesCopied hinzuaddieren kann. Aber so richtig scheint das bei mehreren Dateien auch nicht zu funktionieren, denn BytesCopied geht bei jeder Datei auf 0 zurück wenn mehr als eine Datei kopiert werden soll.
.....

Kann mir da jemand helfen? Auf BytesCopied möchte ich immer die Größe des aktuell kopierten Chunks addieren. Aber 2 Dateien ist BytesCopiedTmp aber so groß wie ein PB und spinnt kurz herum.

:gruebel: So richtig erschließt sich mir nicht, was da eigentlich abläuft. Vor allem "spinnt kurz herum" ist doch sehr obskur. Zeig doch bitte mal den Code.

Gruß
K-H

Luckie 2. Nov 2019 09:01

AW: Systemfehlercode 6 beim Kopieren von Dateien
 
Wozu die Addition? TotalBytesCopied liefert dir doch schon die bereits kopierten Bytes.

DieDolly 2. Nov 2019 11:20

AW: Systemfehlercode 6 beim Kopieren von Dateien
 
Zitat:

Zeig doch bitte mal den Code.
Oben steht er doch.

Zitat:

Wozu die Addition? TotalBytesCopied liefert dir doch schon die bereits kopierten Bytes.
Ich möchte immer die aktuelle Größe des gerade verarbeitetenden Chunks zu einer Variable hinzuaddieren, nicht die gesamte Größe die bis zu dem Zeitpunkt verarbeitet wurde.

Ich habe eine Variable in der steht, wieviele Bytes ingesamt kopiert werden müssen. Bei 2 Dateien mit je 1 GiB also *2.147.483.648‬.
In einer anderen Variable füge ich immer die Bytes hinzu, die der aktuelle Chunk der gerade verarbeitet wurde groß ist. Aus den beiden Variablen errechne ich dann die Prozent für die Ausgabe.

Mit anderen Kopiervarianten funktioniert das alles ohne Probleme, nur mit meinem CopyCallback nicht da ich nicht richtig hinter die Berechnung komme.

Luckie 2. Nov 2019 14:48

AW: Systemfehlercode 6 beim Kopieren von Dateien
 
Ach sooooo. Bei mehreren Dateien willst du den Gesamtfortschritt.

Und dein Code steht leider nicht oben. Du hast nur den Code verlinkt, den du für 64 Bit umgeschrieben hast.

DieDolly 2. Nov 2019 16:00

AW: Systemfehlercode 6 beim Kopieren von Dateien
 
Der Block-basierte Code funktioniert. Der ist aber eh von Windows abhängig und deswegen möchte ich gerne auf die Windowseigenen Mittel zurückgreifen denn ich denke das Memory-Managment ist da besser.

Delphi-Quellcode:
// Der einfachste Fall: stellt euch eine Stringliste vor wo 2 Pfade drin stehen. Diese Dateien sollen kopiert werden. Es sind jeweils mindestens 2 GB, damit man den Fortschritt auch sieht.

// Magie hier, Magie dort... man geht mit einer Schleife durch die Liste und pro Pfad ruft man auf
Winapi.Windows.CopyFileEx(PWideChar(Source), PWideChar(Dest), @CopyCallback, nil, @Cancel, 0);

function CopyCallback(TotalFileSize, TotalBytesCopied, StreamSize, StreamBytesTransferred: Int64; dwStreamNumber, dwCallbackReason: DWORD; hSourceFile, hDestinationFile: THandle)
 : DWORD; stdcall;
var
 CanContinue: Boolean;
const
 PROCESS_CONTINUE = 0;
begin
 CanContinue := not Cancel;

 Result := PROCESS_CONTINUE;
 if dwCallbackReason = CALLBACK_CHUNK_FINISHED then
  begin
   if CanContinue then
    begin
     // Auf die Variable BytesCopied möchte ich hinzuaddieren, wieviele Bytes pro Durchlauf kopiert wurden
    end;
  end;
end;
Und dazu schrieb ich:
Eine Idee wäre, BytesCopiedTemp := BytesCopied - StreamBytesTransferred; . In BytesCopiedTemp steht in meinem Fall jetzt durchgehend 1 MB, den ich auf BytesCopied hinzuaddieren kann. Aber so richtig scheint das bei mehreren Dateien auch nicht zu funktionieren, denn BytesCopied geht bei jeder Datei auf 0 zurück wenn mehr als eine Datei kopiert werden soll.

Delphi-Quellcode:
if CanContinue then
    begin
     BytesCopiedTmp := BytesCopied - StreamBytesTransferred;
     Inc(BytesCopied, BytesCopiedTmp);
    end;
Es ist also eher ein Mathe-Problem hoffe ich.
BytesCopied: eine Variable, die alle bereits kopierten Bytes in Zahlform enthält. Die wird hochgezählt.
Man könnte natürlich einfach die Datei kopieren und bei Erfolg direkt die gesamte Dateigröße draufaddieren aber das passt nicht zum Konzept meines Programmes.

DieDolly 4. Nov 2019 11:19

AW: Systemfehlercode 6 beim Kopieren von Dateien
 
Keiner? :pale:

Der schöne Günther 4. Nov 2019 11:42

AW: Systemfehlercode 6 beim Kopieren von Dateien
 
Ok also ich verstehe es richtig, es geht jetzt mittlerweile um etwas ganz anderes, nämlich "Wie verfolge ich den Gesamtfortschritt wenn ich parallel mittels CopyFileEx mehrere Dateien kopiere, alle aber natürlich den gleichen Callback aufrufen?", richtig?

Ich hätte 2 Ideen:
  1. Jede Copy-Operation bekommt ihren eigenen Callback
  2. Du wertest im Callback einen der Parameter (dwStreamNumber?) aus um daraus zu erkennen, welcher Kopiervorgang bereits wieviel kopiert hat (Doku)

DieDolly 4. Nov 2019 12:01

AW: Systemfehlercode 6 beim Kopieren von Dateien
 
Zitat:

"Wie verfolge ich den Gesamtfortschritt wenn ich parallel mittels CopyFileEx mehrere Dateien kopiere, alle aber natürlich den gleichen Callback aufrufen?"
Fast. Sequentiell.

2 Dateien sollen kopiert werden. Die erste 1 GB, die zweite 2 GB.
Im CopyFileEx steht
Delphi-Quellcode:
Caption := BytesCopied.ToString + ' - ' + BytesCopiedTmp.ToString;
Bei der ersten Datei sieht man in der Caption, wie BytesCopied bis 1 GB hochgeht. BytesCopiedTmp ist durchgehend 1 MB (der Chunk).
Wird angefangen die Zweite Datei zu kopieren, fängt BytesCopied wieder bei 0 an statt bei 1GB weiterzumachen.

Der schöne Günther 4. Nov 2019 12:30

AW: Systemfehlercode 6 beim Kopieren von Dateien
 
Ist doch auch logisch, die beiden Operationen haben nichts miteinander zu tun.
Wenn du es sowieso strikt nacheinander machst kannst du doch den Wert einfach aufaddieren. Verstehe das Problem dahinter ehrlich gesagt nicht.

(Und weshalb sollte es nicht funktionieren zwei Dateien parallel zu kopieren?)

DieDolly 4. Nov 2019 12:32

AW: Systemfehlercode 6 beim Kopieren von Dateien
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1450732)
Wenn du es sowieso strikt nacheinander machst kannst du doch den Wert einfach aufaddieren. Verstehe das Problem dahinter ehrlich gesagt nicht.

Mach ich doch
Delphi-Quellcode:
   if CanContinue then
    begin
     BytesCopiedTmp := BytesCopied - StreamBytesTransferred;
     Inc(BytesCopied, BytesCopiedTmp);

     Caption := BytesCopied.ToString + ' - ' + BytesCopiedTmp.ToString;
    end;

Der schöne Günther 4. Nov 2019 12:40

AW: Systemfehlercode 6 beim Kopieren von Dateien
 
Du musst dir den Wert über den Aufruf des Callbacks hinaus merken. Du brauchst ein Feld in deinem Formular oder wo auch immer du das speichern möchtest, keine lokale Variable.

DieDolly 4. Nov 2019 14:22

AW: Systemfehlercode 6 beim Kopieren von Dateien
 
BytesCopied und BytesCopiedTmp sind global.

Ich glaube ich habs

Delphi-Quellcode:
// BytesCopied und BytesCopiedTmp sind global

function CopyCallback(TotalFileSize, TotalBytesCopied, StreamSize, StreamBytesTransferred: Int64; dwStreamNumber, dwCallbackReason: DWORD; hSourceFile, hDestinationFile: THandle)
 : DWORD; stdcall;
var
 CanContinue: Boolean;
const
 PROCESS_CONTINUE = 0;
begin
 CanContinue := not Cancel;

 Result := PROCESS_CONTINUE;
 if dwCallbackReason = CALLBACK_CHUNK_FINISHED then
  begin
   if CanContinue then
    begin
     Inc(BytesCopied, StreamBytesTransferred - BytesCopiedTmp);
     BytesCopiedTmp := StreamBytesTransferred;
    end;
  end;
end;

procedure Kopiere;
begin
 BytesCopiedTmp := 0;
 Winapi.Windows.CopyFileEx(quelle, ziel), @CopyCallback, nil, @Cancel, 0);
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:51 Uhr.

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