Autor |
Beitrag |
idefix123456
      
Beiträge: 23
|
Verfasst: Mi 23.11.11 19:59
Hallo,
Ich muss mit Delphi (RadStudio) eine Datei von A nach B kopieren und es muss Unbedingt ein Vergleich durchgeführt werden. D.h. Es soll byte-für-byte, oder besser noch bit-für-bit von beiden Dateien verglichen werden (Quelle = Ziel). Sodass wirklich Sichergestellt werden kann, das die Zieldatei zu 100% der Quelldatei entspricht!
Habe vorhin zwar schon einen Code erstellt, kurze Erklärung...
- Zuerst wird die Datei Mittels CopyFile von A nach B Kopiert.
- Dannach werden zwei Parallele Threads gestartet...
- ...Thread1 Erzeugt einen MD5 Hash der Quelldatei
- ...Thread2 Erzeugt einen MD5 Hash der Zieldatei
- Anschließend werden beide MD5 Hashes verglichen...
- ...Bei Fehler wird die Zieldatei wieder gelöscht, und das Kopieren erneut gestartet
Das ganze Funktioniert zwar, ist aber Extrem langsam.
Das Kopieren an sich geht ja schnell, Aber das Überprüfen Dauert fast Doppelt so lang wie das Kopieren.
Kennt ihr eine Bessere Schnellere Lösung?
Es muss ja nicht unbedingt mittels Hash abgeglichen werden es ist ja eigentlich nur Wichtig das beide Dateien irgendwie Verglichen werden um sicherzustellen das diese 100% identisch sind...
Wer kann helfen?
Danke!
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 23.11.11 20:14
Wohin schreibst du die Datei denn? Wodurch werden denn dabei die Fehler verursacht?
Ein Hash macht hier jedenfalls wenig Sinn, denn dafür musst du in jedem die komplette Datei lesen, auch wenn gleich am Anfang eine Differenz vorkommt.
Wie der Vergleich möglich ist, hängt vom Medium ab, denn auf einer lokalen Festplatte z.B. würde das ja kaum Sinn machen. Insofern ist erst einmal wichtig zu wissen worum es eigentlich geht.
|
|
Delphi-Laie
      
Beiträge: 1600
Erhaltene Danke: 232
Delphi 2 - RAD-Studio 10.1 Berlin
|
Verfasst: Do 24.11.11 00:29
idefix123456 hat folgendes geschrieben : | Es soll byte-für-byte, oder besser noch bit-für-bit von beiden Dateien verglichen werden (Quelle = Ziel). Sodass wirklich Sichergestellt werden kann, das die Zieldatei zu 100% der Quelldatei entspricht! |
Dazu reicht der byteweise Vergleich aber völlig! Ganz im Gegensatz sogar: Der bitweise Zugriff ist unnötig kompliziert und langsam.
|
|
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Do 24.11.11 08:15
Vielleicht hilft dir das: stackoverflow.com/qu...hash-of-a-large-file
Bedenke aber dass Hashen keine 100% Sicherheit bietet (wenn auch fast  ). Interessant wäre evtl auch Code von dem Teil, wo du die Datei einliest.
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Do 24.11.11 08:34
Ein Hash bringt IMHO nur etwas wenn Du die Hashes der vorhandenen Dateien aufheben kannst, sie sich also nicht mehr ändern, und Du dir das neue Hashen der vorhandenen Daten Sparen kannst, ansonsten hilft Dir vielleicht das:
stackoverflow.com/qu...ntent-of-two-tstream
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
rushifell
      
Beiträge: 306
Erhaltene Danke: 14
|
Verfasst: Do 24.11.11 18:03
Wäre das mit einer Repeat-Schleife nicht schneller?
|
|
idefix123456 
      
Beiträge: 23
|
Verfasst: Fr 25.11.11 17:00
Hallo,
Danke für die vielen Antworten.
Ich habe mir das ganze nochmal durch den kopf gehen lassen, und mir überlegt, das die schnellste Möglichkeit Eigentlich diese sein müsste...
Beispiel:
Ich habe eine Quelldatei mit 50GB. Diese Soll von Laufwerk C:\ nach Laufwerk D:\ Kopiert werden, und zusätzlich auf Gleichheit überprüft werden!
1. Lese von der Datei die ersten z.b. 50KB und schreibe sie in den RAM
2. Entnehme die 50KB aus dem RAM und schreibe sie auf das Ziellaufwerk (D:\)
3. Lese die gerade Geschriebenen 50KB vom Ziellaufwerk (D:\), und vergleiche mit den 50KB aus dem RAM
4.1 Beide Blöcke sind identisch, dann lese den Nächsten 50KB Block d.h. es beginnt wieder bei 1.
4.2 Beide Blöcke sind nicht identisch, dann entferne den letzten geschriebenen letzten 50KB Block von Laufwerk (D:\) und Kopiere diese Block erneut!
Ich hoff ich konnte das verständlich Erklären. Wie ich das vorhabe zu machen... Fehlt nur noch die Umsetzung...
Hoffe jemand kann helfen...
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 25.11.11 17:52
Mit einer derart kleinen Blockgröße dauert das ewig. Zwischen 1 und 8 MiB oder so wären da wohl besser geeignet.
Einfacher dürften hier MMFs sein, da sich Windows hier um das puffern der Daten kümmert. Da kannst du die Blöcke auch einfach mit z.B. CompareMem vergleichen.
Wenn du aber beim Kopieren zwischen zwei lokalen Festplatten Übertragungsfehler hast, dann hast du wohl eher ganz andere Probleme. 
|
|
idefix123456 
      
Beiträge: 23
|
Verfasst: Fr 25.11.11 19:13
Hallo,
Das mit dem von Festplatte auf Festplatte kopieren ist nur ein Beispiel um das ganze einfach zu erklären. Es geht z.b. auch darum Daten auf ein Netzlaufwerk / Netzwerkfreigaben / FTP von Entfernten Servern etc. zu Kopieren, wodurch hin und wieder auch mal Fehler auftreten können.
Das mit der Blockgröße sollte ja kein Problem sein eine sinnvolle Größe zu finden...
Im Moment ist es mir eigentlich nur wichtig einen Code zu schreiben welcher eine Datei von A nach B kopiert und anschließend oder während dem Kopieren auf Korrektheit Prüft!
Könnte mir jemand einen Beispielcode Posten Welcher Eine Datei Blockweise ließt, diesen Block vom RAM aufs Ziellaufwerk schreibt und dann Überprüft, am besten so wie im vorherigen Post von mir beschrieben.
Was sind MMFs?
Danke für Antworten...
|
|
Delphi-Laie
      
Beiträge: 1600
Erhaltene Danke: 232
Delphi 2 - RAD-Studio 10.1 Berlin
|
Verfasst: Fr 25.11.11 22:38
Wird das Prüfen nicht vom Betriebsprogramm bewerkstelligt? Zu DOS-Zeiten gab es mal einen Befehl für die config.sys namens verify=on (und / oder auch für die autoexec.bat ohne Gleichheits-, dafür mit Leerzeichen). Wie macht es NT-basiertes Windows? Automatisch? Immer? Ist das zu- oder abschaltbar? Damals konnte man auch noch die Größe des Kopierpuffers einstellen, das waren noch Zeiten.... Stehe diesbzeüglich leider auch ein wenig im Regen, aber wenn Windows vieles automatisch tut (ohne Prüfung wäre es m.E. nicht zeitgemäß, obwohl auf der anderen Seite Festpaltten und USB-Speicherstifte kaum Speicherfehler haben). Edit: Also eben in meinem Windows 2000 die Commandlineshell (cmd.exe) aufgerufen: Kennt verify, ist aber ausgeschaltet (voreingestellter Standard?).
Anscheinend Multimediafiles, oder in primitiver angelsächsicher Orthographie: multimedia files.
Zuletzt bearbeitet von Delphi-Laie am Sa 26.11.11 15:13, insgesamt 1-mal bearbeitet
|
|
Lemmy
      
Beiträge: 792
Erhaltene Danke: 49
Windows 7 / 10; CentOS 7; LinuxMint
Delphi 7-XE10.1, VS 2015
|
Verfasst: Fr 25.11.11 22:52
hi,
ich vermute, dass hier eher Memory Mapped files gemeint sind....
Grüße
|
|
Delphi-Laie
      
Beiträge: 1600
Erhaltene Danke: 232
Delphi 2 - RAD-Studio 10.1 Berlin
|
Verfasst: Fr 25.11.11 22:57
Ach so, eine Form der Interprozeßkommunikation. Dazu gibt es z.B. im Delphitreff eine gute Einführung, aber auch bei Assarbad findet man Substantielles dazu. Doch warum sollte man Dateien im Hauptspeicher des Computers auf fehlerfreis Schreiben kontrollieren?
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 25.11.11 23:01
Delphi-Laie hat folgendes geschrieben : | Ach so, eine Form der Interprozeßkommunikation. |
Nicht wirklich. Kann man zwar auch dafür nutzen, aber eigentlich benutzt man MMF's um mit großen Dateien zu arbeiten.
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 25.11.11 23:31
Delphi-Laie hat folgendes geschrieben : | Wird das Prüfen nicht vom Betreibsprogramm bewerkstelligt? |
Auf lokalen Datenträgern schon, aber schon beim Brennen von optischen Datenträgern nicht mehr. Ebensowenig bei Übertragungen via FTP usw.
Unter anderem deshalb hatte ich gefragt wohin denn die Reise der Daten geht.
Delphi-Laie hat folgendes geschrieben : |
Anscheinend Multimediafiles, oder in primitiver angelsächsicher Orthographie: multimedia files. |
Memory Mapped Files bilden eine Datei im Arbeitsspeicher ab, das heißt man definiert nur welcher Teil im Arbeitsspeicher verfügbar sein soll und kann danach direkt über einen Pointer auf diesen Speicher auf die Daten zugreifen, den Rest macht Windows. Auf diese Weise kann man sehr leicht auch zwei solche Speicherbereiche vergleichen (oder eben einen solchen Bereich mit einem Puffer).
Auf jeden Fall erreicht man so eine enorme Geschwindigkeit (insbesondere beim Zugriff auf viele kleine Bereiche der Datei), da Windows selbst den Zugriff auf die Festplatte optimiert, auch abhängig von anderen anliegenden Operationen.
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Sa 26.11.11 17:10
Die Zieldatei musst du ja mindestens 1x schreiben und mindestens 1x lesen. Du kannst also höchstens noch optimieren, dass die Quelldatei nur 1x gelesen wird, statt 2x. Den Hash könntest du während dem Kopieren bereits berechnen, jedoch bietet dir das nicht die 100%-ige Sicherheit, wie bereits genannt wurde.
Daher bleibt dir nur noch die Möglichkeit, den Vergleich nach dem vollständigen Kopieren zu machen. Und da wird wahrscheinlich die Geschwindigkeit der Platte der Flaschenhals sein.
Aber auch das bietet dir nicht die 100%-ige Sicherheit, wenn der Datenträger einen Schreibcache verwendet. Wenn also dein Leben davon abhängt, würde ich die Platte abhängen, wieder anhängen, und dann nochmals vergleichen 
|
|
hathor
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: So 27.11.11 20:28
Das BS macht doch das automatisch:
Zyklische Redundanzprüfung
de.wikipedia.org/wik...edundanzpr%C3%BCfung
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: So 27.11.11 21:23
Ich denke nicht, dass ein Betriebssystem nach dem Schreiben eine Leseprüfung durchführt und irgendwelche Checksummen berechnet. Dazu müsste der Festplattenkopf ständig hin und herspringen um nach dem Schreiben zu Lesen.
|
|
hathor
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: So 27.11.11 21:50
Fehlerkorrektur-Daten sind immer dabei: HDD, CD, DVD, BD, Network...
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: So 27.11.11 22:04
Es geht darum die geschrieben Daten zu überprüfen. Dazu reicht es nicht, die Daten mit EECs zu speichern oder Checksummen zu übertragen. Ausserdem bieten Checksummen keine 100%ige Sicherheit.
Wenn du 100% sicherstellen willst, dass die Daten gelesen werden können, musst du die Daten auch lesen - und zwar über die ganze Kette mit den gleichen Mechanismen wie du die Daten später auch tatsächlich wieder lesen können willst.
Wenn du Daten auf ein Magnetband schreibst und das Band seitlich verschoben war, merkst du das vielleicht erst daran, dass du die Daten am Ende nicht lesen kannst. Möglicherweise kannst du die Daten nur mit dem Gerät lesen, mit dem es geschrieben wurde, usw. Da kannst du lange EECs mitschreiben, das bringt dir am Ende nichts.
Daher sollte man Backups auch nicht nur schreiben sondern auch mal testen - und zwar genau so, wie du das im Ernstfall tun würdest.
|
|
Boldar
      
Beiträge: 1555
Erhaltene Danke: 70
Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
|
Verfasst: Mo 28.11.11 22:19
delfiphan hat folgendes geschrieben : |
Wenn du 100% sicherstellen willst, dass die Daten gelesen werden können, musst du die Daten auch lesen - und zwar über die ganze Kette mit den gleichen Mechanismen wie du die Daten später auch tatsächlich wieder lesen können willst.
Wenn du Daten auf ein Magnetband schreibst und das Band seitlich verschoben war, merkst du das vielleicht erst daran, dass du die Daten am Ende nicht lesen kannst. Möglicherweise kannst du die Daten nur mit dem Gerät lesen, mit dem es geschrieben wurde, usw. Da kannst du lange EECs mitschreiben, das bringt dir am Ende nichts.
Daher sollte man Backups auch nicht nur schreiben sondern auch mal testen - und zwar genau so, wie du das im Ernstfall tun würdest. |
Auch dann gibt es keine 100%tige Sicherheit. Es könnte ja durch ein Übertragungsfehler genau das passende Bitmuster entstehen, obwohl die Datei eigentlich nicht geschrieben wurde.
|
|