Warum klappt Binary bei mir nicht
-
@hustbaer sagte in Warum klappt Binary bei mir nicht:
using (var fs2 = new FileStream(pDsn2, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan))
Wenn ich diese Parameter hinzufüge ( 4 und 5)
FileStream fs2 = new FileStream(pDsn2, FileMode.Open, FileAccess.Read, 4096, FileOptions.SequentialScan);
dann wird für (4) = 4096 angezeigt: CS1503: Konvertierung von int in System.IO.FileShare nicht möglich.
und für (5) = FileOptions.SequentialScan wird angezeigt:
CS1503: Konvertierung von System.IO.FileOptions in int nicht möglich.Mit ALT+Eingabe wird das Statement folgendermaßen korrigiert
FileStream fs2 = new FileStream(pDsn2, FileMode.Open, FileAccess.Read, (FileShare)4096, (int)FileOptions.SequentialScan);
Beim Ausführen erhalte ich allerdings einen Fehler:
System.ArgumentOutOfRangeException: "Der Enumerationswert lag außerhalb des gültigen Bereichs. Parametername: share"Ich benutze allerdings kein USING.
-
@hkdd
Du hastFileShare.Read
unterschlagen.
-
@hustbaer
JA, das war es - trotz meiner neuen Linsen in den Augen habe ich das übersehen.
Was bedeuten diese 4096, ist das der Lesepuffer oder nimmt Read dann die angegebene Anzahl Bytes zum lesen ?
-
Was bedeuten diese 4096, ist das der Lesepuffer oder nimmt Read dann die angegebene Anzahl Bytes zum lesen ?
Das ist die Grösse für den internen Puffer der File-Streams. Wenn kleinere Lese bzw. Schreib-Operationen gemacht werden, dann gehen die über den Puffer. Oft liest bzw. schreibt man Dateien ja in kleinen Stücken, da bringt das dann einiges.
Lese bzw. Schreib-Operationen die grösser als der interne Puffer sind werden allerdings direkt an die OS Funktionen weitergeleitet. Für dein Programm ist der Puffer also irrelevant. Alle Konstruktoren wo man
FileOptions
angeben kann erfordern allerdings dass man die Puffergrösse angibt. Also hab ich einfach den Default-Wert von 4096 genommen.
-
@hkdd sagte in Warum klappt Binary bei mir nicht:
Ich benutze allerdings kein USING.
Macht in dem Fall keinen Unterschied. Bloss: wieso verwendest du es nicht?
-
@hustbaer
Ein wenig schneller scheint es zu sein. Das erste Ergebnis ist von gestern und das zweite von heute~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ============================================================ 82 Unterordner gefunden 2.446 Dateien gefunden - davon 2.446 identische Dateien verglichen. Es wurden 208.144.569.612 Bytes = 203.266.181 K-Bytes verglichen. 133.902 Puffer gelesen, Pufferlänge: 1.572.864 Bytes. Start 19:24:40 Ende 19:50:57 Dauer 00:26:17.5 ===================================================<Ende>=== ESC = Programm beenden ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CompCs - Dateien vergleichen - (C) 12.12.2022 Hartmut aus Dresden --------------------------------------------------------------- Parameter: N:\VideosN N:\VideosN --------------------------------------------------------------- Vergleich: N:\VideosN\ mit: N:\VideosN\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ============================================================ 82 Unterordner gefunden 2.446 Dateien gefunden - davon 2.446 identische Dateien verglichen. Es wurden 208.144.569.612 Bytes = 203.266.181 K-Bytes verglichen. 133.902 Puffer gelesen, Pufferlänge: 1.572.864 Bytes. Start 16:08:58 Ende 16:34:20 Dauer 00:25:22.0 ===================================================<Ende>=== ESC = Programm beenden ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Ich habe versucht bei den beiden FileStream Anweisungen USING davor zu schreiben und nach dem zweiten Using den Rest mit {...} einzuklammern - das klappt aber nicht. Ohne USING - alles ist OK.
//================================================= // Datei 1 und 2 lesen und vergleichen //================================================= private bool VergleicheDateien(string pDsn1, string pDsn2, Int64 lenFile, string pPfad) { bool rc; Int64 RestLen = lenFile; // Dateilänge beider Dateien Int64 LeseLen = Math.Min(RestLen, MaxPuffL); FileStream fs1 = new FileStream(pDsn1, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan); FileStream fs2 = new FileStream(pDsn2, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan); while (LeseLen > 0) { Application.DoEvents(); if (Abbruch > 0) { return false; } GesBytes += LeseLen; // Anzahl gelesene Bytes gesamt this.Text = "CompHk " + GesBytes.ToString("###,###,###,###,##0") + " Bytes " + pPfad; fs1.Read(ByPu1, 0, (int)LeseLen); fs2.Read(ByPu2, 0, (int)LeseLen); AnzPuff++; // Anzahl verglichene Puffer if (LeseLen < 9) { for (int b = 0; b < LeseLen; b++) { if (ByPu1[b] != ByPu2[b]) { goto VerglErr; // Vergleich abbrechen } } break; } switch (VergleichsMethode) // Welche Art des Vergleiches { case compSequenceEqual: // C# interne Funktion if (!(ByPu1.Take((int)LeseLen).SequenceEqual(ByPu2.Take((int)LeseLen)))) { goto VerglErr; // Vergleich abbrechen } break; case compMemCmp: // [DllImport] msvcrt.dll if (memcmp(ByPu1, ByPu2, LeseLen) != 0) { goto VerglErr; // Vergleich abbrechen } break; case compForNxt: // C# interner Byte-für-Byte-Vergleich for (int b = 0; b < LeseLen; b++) { if (ByPu1[b] != ByPu2[b]) { goto VerglErr; // Vergleich abbrechen } } break; case compUnsafe: // unsafe MemCmp if (!MemCmp(ByPu1, ByPu2, (int)LeseLen)) { goto VerglErr; // Vergleich abbrechen } break; case compRtlCompareMemory: // [DllImport] kernel32.dll RtlCompareMemory IntPtr len = (IntPtr)LeseLen; //IntPtr rc = RtlCompareMemory(ByPu1, ByPu2, len); var rCod = RtlCompareMemory(ByPu1, ByPu2, len); if (rCod != len) { goto VerglErr; // Vergleich abbrechen } break; case compCompareByteArray: // [DllImport] CompareByteArray.dll von HK if (CompareByteArray(ByPu1, ByPu2, (int)LeseLen) != 0) { goto VerglErr; // Vergleich abbrechen } break; } // switch (VergleichsMethode) RestLen -= LeseLen; LeseLen = Math.Min(RestLen, MaxPuffL); } // while (LeseLen > 0) AnzFilesOK++; rc = true; goto UpEnde; // Vergleich abbrechen VerglErr: ByteDiff++; // es gibt Differenzen rc = false; UpEnde: fs1.Close(); fs2.Close(); return rc; } // static bool VergleicheDateien(string pDsn1, string pDsn2, Int64 lenFile)
-
@hkdd
Hab's nicht ausprobiert, aber ich nehme an der Grund für die Fehler ist dass dugoto
s verwendest. Ich würde empfehlen aufgoto
zu verzichten. Weiters wäre es praktisch die eigentliche Vergleichs-Funktion vom Rest des Programms zu entkoppeln. z.B. von der Aktualisierung des User-Interface und dem Test ob abgebrochen werden soll. Könnte dann z.B. so aussehen:private bool VergleicheDateien(string pDsn1, string pDsn2, Int64 lenFile, string pPfad) { int res = VergleicheDateien0(pDsn1, pDsn2, lenFile, leseLen => { Application.DoEvents(); if (Abbruch > 0) { return false; } GesBytes += leseLen; // Anzahl gelesene Bytes gesamt AnzPuff++; // Anzahl verglichene Puffer this.Text = "CompHk " + GesBytes.ToString("###,###,###,###,##0") + " Bytes " + pPfad; return true; }); switch (res) { case 0: ByteDiff++; return false; case 1: AnzFilesOK++; return true; default: return false; } } private int VergleicheDateien0(string pDsn1, string pDsn2, Int64 lenFile, Func<long, bool> fortschrittsCallback) { Int64 RestLen = lenFile; // Dateilänge beider Dateien Int64 LeseLen = Math.Min(RestLen, MaxPuffL); using (FileStream fs1 = new FileStream(pDsn1, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan)) using (FileStream fs2 = new FileStream(pDsn2, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan)) { while (LeseLen > 0) { if (!fortschrittsCallback(LeseLen)) { return -1; } fs1.Read(ByPu1, 0, (int)LeseLen); fs2.Read(ByPu2, 0, (int)LeseLen); if (LeseLen < 9) { for (int b = 0; b < LeseLen; b++) { if (ByPu1[b] != ByPu2[b]) { return 0; } } break; } switch (VergleichsMethode) // Welche Art des Vergleiches { case compSequenceEqual: // C# interne Funktion if (!(ByPu1.Take((int)LeseLen).SequenceEqual(ByPu2.Take((int)LeseLen)))) { return 0; } break; case compMemCmp: // [DllImport] msvcrt.dll if (memcmp(ByPu1, ByPu2, LeseLen) != 0) { return 0; } break; case compForNxt: // C# interner Byte-für-Byte-Vergleich for (int b = 0; b < LeseLen; b++) { if (ByPu1[b] != ByPu2[b]) { return 0; } } break; case compUnsafe: // unsafe MemCmp if (!MemCmp(ByPu1, ByPu2, (int)LeseLen)) { return 0; } break; case compRtlCompareMemory: // [DllImport] kernel32.dll RtlCompareMemory IntPtr len = (IntPtr)LeseLen; //IntPtr rc = RtlCompareMemory(ByPu1, ByPu2, len); var rCod = RtlCompareMemory(ByPu1, ByPu2, len); if (rCod != len) { return 0; } break; case compCompareByteArray: // [DllImport] CompareByteArray.dll von HK if (CompareByteArray(ByPu1, ByPu2, (int)LeseLen) != 0) { return 0; } break; } // switch (VergleichsMethode) RestLen -= LeseLen; LeseLen = Math.Min(RestLen, MaxPuffL); } // while (LeseLen > 0) return 1; } }
Die neue Funktion
VergleicheDateien0
ist jetzt völlig unabhängig vom User-Interface. Was viele Vorteile hat, z.B. dass man sie dadurch unabhängig vom User-Interface testen kann.
-
ps:
Hast duReadAsync
auch mal ausprobiert?var r1 = fs1.ReadAsync(ByPu1, 0, (int)LeseLen); fs2.Read(ByPu2, 0, (int)LeseLen); r1.Wait();
-
@hustbaer
leider bin ich kein so ausgefuchster Programmierer, wie Du, aber ich kann viel von Dir lernen - DANKE dafür und auch an all die anderen hier im Forum.
Ich habe jetzt erst einmal die USINGs eingebaut und die GOTOs entfernt. Braucht man bei USING keine CLOSE mehr ?
ReadAsync werde ich nun auch noch ausprobieren, ob damit noch ein paar Sekunden herauszuholen sind.//================================================= // Datei 1 und 2 lesen und vergleichen //================================================= private bool VergleicheDateien(string pDsn1, string pDsn2, Int64 lenFile, string pPfad) { bool rc = true; Int64 RestLen = lenFile; // Dateilänge beider Dateien Int64 LeseLen = Math.Min(RestLen, MaxPuffL); using (FileStream fs1 = new FileStream(pDsn1, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan)) using (FileStream fs2 = new FileStream(pDsn2, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan)) { while (LeseLen > 0 && rc) { Application.DoEvents(); if (Abbruch > 0) { return false; } GesBytes += LeseLen; // Anzahl gelesene Bytes gesamt this.Text = "CompHk " + GesBytes.ToString("###,###,###,###,##0") + " Bytes " + pPfad; fs1.Read(ByPu1, 0, (int)LeseLen); fs2.Read(ByPu2, 0, (int)LeseLen); AnzPuff++; // Anzahl verglichene Puffer if (LeseLen < 9) { for (int b = 0; b < LeseLen; b++) { if (ByPu1[b] != ByPu2[b]) { rc = false; // Es gibt Differenzen, Vergleich abbrechen } } break; } switch (VergleichsMethode) // Welche Art des Vergleiches { case compSequenceEqual: // C# interne Funktion if (!(ByPu1.Take((int)LeseLen).SequenceEqual(ByPu2.Take((int)LeseLen)))) { rc = false; // Es gibt Differenzen, Vergleich abbrechen } break; case compMemCmp: // [DllImport] msvcrt.dll if (memcmp(ByPu1, ByPu2, LeseLen) != 0) { rc = false; // Es gibt Differenzen, Vergleich abbrechen } break; case compForNxt: // C# interner Byte-für-Byte-Vergleich for (int b = 0; b < LeseLen; b++) { if (ByPu1[b] != ByPu2[b]) { rc = false; // Es gibt Differenzen, Vergleich abbrechen } } break; case compUnsafe: // unsafe MemCmp if (!MemCmp(ByPu1, ByPu2, (int)LeseLen)) { rc = false; // Es gibt Differenzen, Vergleich abbrechen } break; case compRtlCompareMemory: // [DllImport] kernel32.dll RtlCompareMemory IntPtr len = (IntPtr)LeseLen; //IntPtr rc = RtlCompareMemory(ByPu1, ByPu2, len); var rCod = RtlCompareMemory(ByPu1, ByPu2, len); if (rCod != len) { rc = false; // Es gibt Differenzen, Vergleich abbrechen } break; case compCompareByteArray: // [DllImport] CompareByteArray.dll von HK if (CompareByteArray(ByPu1, ByPu2, (int)LeseLen) != 0) { rc = false; // Es gibt Differenzen, Vergleich abbrechen } break; } // switch (VergleichsMethode) RestLen -= LeseLen; LeseLen = Math.Min(RestLen, MaxPuffL); } // while (LeseLen > 0 && rc) } if (rc) { AnzFilesOK++; } // es gibt keine Differenzen else { ByteDiff++; } // es gibt Differenzen //fs1.Close(); //fs2.Close(); return rc; } // static bool VergleicheDateien(string pDsn1, string pDsn2, Int64 lenFile)
-
@hustbaer sagte in Warum klappt Binary bei mir nicht:
var r1 = fs1.ReadAsync(ByPu1, 0, (int)LeseLen);
fs2.Read(ByPu2, 0, (int)LeseLen);
r1.Wait();var r1 = fs1.ReadAsync(ByPu1, 0, (int)LeseLen);
r1 ist m.E. doch die zurück gegebene tatsächlich gelesene Länge, also ein int-Wert.
Macht r1.Wait() dann einen Sinn ?In den gefundenen ReadAsync Beispielen sieht es etwa so aus
var r1ReadLen = await fs1.ReadAsync(ByPu1, 0, (int)LeseLen);
-
@hkdd sagte in Warum klappt Binary bei mir nicht:
Braucht man bei USING keine CLOSE mehr ?
Nein braucht man nicht dafür ist das using da, damit man nicht vergessen kann close/dispose aufzurufen.
Besonders falls eine exception geworfen wird, wird durch das using statemant definitiv immer beim verlassen des blocks close/dispose aufgerufen.
-
@hkdd sagte in Warum klappt Binary bei mir nicht:
var r1 = fs1.ReadAsync(ByPu1, 0, (int)LeseLen);
r1 ist m.E. doch die zurück gegebene tatsächlich gelesene Länge, also ein int-Wert.
Macht r1.Wait() dann einen Sinn ?In den gefundenen ReadAsync Beispielen sieht es etwa so aus
var r1ReadLen = await fs1.ReadAsync(ByPu1, 0, (int)LeseLen);
Alle asynchronen Methoden liefern ein Task (für
void
) oder Task<T>-Objekt zurück, auch Stream.ReadAsync.
Der eigentliche Rückgabewert steht dann in Result.
-
@Th69
Im Debugger habe ich mir r1 angesehen. r1.Result ist die gelesene Länge. Es gibt andere Infos. Und offenbar auch Funktionen, wie r1.Wait(), die man benutzen kann.ich habe jetzt beide Dateien mit ReadAsync gelesen und die Puffer vergrößert.
Werden die Puffer tatsächlich zeitlich parallel / gleichzeitig und nicht mehr nacheinander gelesen ?//================================================= // Datei 1 und 2 lesen und vergleichen //================================================= private bool VergleicheDateien(string pDsn1, string pDsn2, Int64 lenFile, string pPfad) { bool rc = true; Int64 RestLen = lenFile; // Dateilänge beider Dateien Int64 LeseLen = Math.Min(RestLen, MaxPuffL); using (FileStream fs1 = new FileStream(pDsn1, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan)) using (FileStream fs2 = new FileStream(pDsn2, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan)) { while (LeseLen > 0 && rc) { Application.DoEvents(); if (Abbruch > 0) { return false; } GesBytes += LeseLen; // Anzahl gelesene Bytes gesamt this.Text = "CompHk " + GesBytes.ToString("###,###,###,###,##0") + " Bytes " + pPfad; var r1 = fs1.ReadAsync(ByPu1, 0, (int)LeseLen); var r2 = fs2.ReadAsync(ByPu2, 0, (int)LeseLen); r1.Wait(); r2.Wait(); AnzPuff++; // Anzahl verglichene Puffer if (LeseLen < 9) { for (int b = 0; b < LeseLen; b++) { if (ByPu1[b] != ByPu2[b]) { rc = false; // Es gibt Differenzen, Vergleich abbrechen } } break; } switch (VergleichsMethode) // Welche Art des Vergleiches { case compSequenceEqual: // C# interne Funktion if (!(ByPu1.Take((int)LeseLen).SequenceEqual(ByPu2.Take((int)LeseLen)))) { rc = false; // Es gibt Differenzen, Vergleich abbrechen } break; case compMemCmp: // [DllImport] msvcrt.dll if (memcmp(ByPu1, ByPu2, LeseLen) != 0) { rc = false; // Es gibt Differenzen, Vergleich abbrechen } break; case compForNxt: // C# interner Byte-für-Byte-Vergleich for (int b = 0; b < LeseLen; b++) { if (ByPu1[b] != ByPu2[b]) { rc = false; // Es gibt Differenzen, Vergleich abbrechen } } break; case compUnsafe: // unsafe MemCmp if (!MemCmp(ByPu1, ByPu2, (int)LeseLen)) { rc = false; // Es gibt Differenzen, Vergleich abbrechen } break; case compRtlCompareMemory: // [DllImport] kernel32.dll RtlCompareMemory IntPtr len = (IntPtr)LeseLen; //IntPtr rc = RtlCompareMemory(ByPu1, ByPu2, len); var rCod = RtlCompareMemory(ByPu1, ByPu2, len); if (rCod != len) { rc = false; // Es gibt Differenzen, Vergleich abbrechen } break; case compCompareByteArray: // [DllImport] CompareByteArray.dll von HK if (CompareByteArray(ByPu1, ByPu2, (int)LeseLen) != 0) { rc = false; // Es gibt Differenzen, Vergleich abbrechen } break; } // switch (VergleichsMethode) RestLen -= LeseLen; LeseLen = Math.Min(RestLen, MaxPuffL); } // while (LeseLen > 0 && rc) } if (rc) { AnzFilesOK++; } // es gibt keine Differenzen else { ByteDiff++; } // es gibt Differenzen return rc; } // static bool VergleicheDateien(string pDsn1, string pDsn2, Int64 lenFile)
Hier ein paar Ergebnisse mit etwas größeren Puffern
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CompCs - Dateien vergleichen - (C) 13.12.2022 Hartmut aus Dresden --------------------------------------------------------------- Parameter: N:\VideosN N:\VideosN --------------------------------------------------------------- Vergleich: N:\VideosN\ mit: N:\VideosN\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ============================================================ 82 Unterordner gefunden 2.446 Dateien gefunden - davon 2.446 identische Dateien verglichen. Es wurden 208.144.569.612 Bytes = 203.266.181 K-Bytes verglichen. 133.902 Puffer gelesen, Pufferlänge: 1.572.864 Bytes. Start 07:30:05 Ende 07:55:57 Dauer 00:25:52.0 ===================================================<Ende>=== ESC = Programm beenden ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CompCs - Dateien vergleichen - (C) 14.12.2022 Hartmut aus Dresden --------------------------------------------------------------- Parameter: N:\VideosN N:\VideosN --------------------------------------------------------------- Vergleich: N:\VideosN\ MaxPuffL = 0x00180000; // Pufferlänge mit: N:\VideosN\ var r1 = fs1.ReadAsync(ByPu1, 0, (int)LeseLen); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ============================================================ 82 Unterordner gefunden 2.446 Dateien gefunden - davon 2.446 identische Dateien verglichen. Es wurden 208.144.569.612 Bytes = 203.266.181 K-Bytes verglichen. 133.902 Puffer gelesen, Pufferlänge: 1.572.864 Bytes. Start 08:24:28 Ende 08:50:29 Dauer 00:26:00.4 ===================================================<Ende>=== ESC = Programm beenden ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CompCs - Dateien vergleichen - (C) 14.12.2022 Hartmut aus Dresden --------------------------------------------------------------- Parameter: N:\VideosN N:\VideosN --------------------------------------------------------------- Vergleich: N:\VideosN\ MaxPuffL = 0x08000000; // Pufferlänge mit: N:\VideosN\ var r1 = fs1.ReadAsync(ByPu1, 0, (int)LeseLen); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ============================================================ 82 Unterordner gefunden 2.446 Dateien gefunden - davon 2.446 identische Dateien verglichen. Es wurden 208.144.569.612 Bytes = 203.266.181 K-Bytes verglichen. 3.424 Puffer gelesen, Pufferlänge: 134.217.728 Bytes. Start 08:51:59 Ende 09:19:00 Dauer 00:27:00.9 ===================================================<Ende>=== ESC = Programm beenden ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CompCs - Dateien vergleichen - (C) 14.12.2022 Hartmut aus Dresden --------------------------------------------------------------- Parameter: N:\VideosN N:\VideosN --------------------------------------------------------------- Vergleich: N:\VideosN\ MaxPuffL = 0x00800000; // Pufferlänge mit: N:\VideosN\ fs1 und fs2 ReadAsync ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ============================================================ 82 Unterordner gefunden 2.446 Dateien gefunden - davon 2.446 identische Dateien verglichen. Es wurden 208.144.569.612 Bytes = 203.266.181 K-Bytes verglichen. 26.474 Puffer gelesen, Pufferlänge: 8.388.608 Bytes. Start 09:23:35 Ende 09:48:57 Dauer 00:25:21.5 ===================================================<Ende>=== ESC = Programm beenden ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
Werden die Puffer tatsächlich zeitlich parallel / gleichzeitig und nicht mehr nacheinander gelesen ?
Ja. Dazu reicht es allerdings wenn man einen der beiden Reads (den ersten) "async" macht. Das erste
ReadAsync
startet dabei das Lesen des Blocks aus dem 1. File. Daneben läuft das Programm weiter und kann den 2. Read synchron machen. Wenn der 2. Read fertig ist, muss man noch warten dass der erste, asynchrone auch fertig ist - könnte ja sein dass der 2. Read aus irgend einem Grund schneller war. Das macht dasr1.Wait()
.Bringt aber nichts, wenn du 2x vom selben Laufwerk liest. Weil Zugriffe auf das selbe Laufwerk werden nicht schneller, nur weil man 2 parallel macht. Es könnte die Sache sogar erheblich langsamer machen. Wenn es allerdings verschiedene Laufwerke sind, dann bringt es u.U. viel, denn dann können beide Laufwerke gleichzeitig lesen.
Kann, muss aber nicht, weil das OS evtl. "read ahead" macht. Ob das passiert und wie gut es funktioniert hängt von einigen Faktoren ab. U.a. der OS Version und der Puffergrösse. (Read ahead wird nur bis zu einer maximalen Puffergrösse gemacht.)
Aktuell scheinst du mit 2x dem selben Verzeichnis zu testen. Das macht mMn. eher wenig Sinn wenn du Performance-Tests machen willst. Wenn du das Programm auf den Einsatz mit 2 verschiedenen Laufwerken optimieren willst, dann solltest du auch mit 2 verschiedenen Laufwerken testen. Bzw. wenn du das Programm auf den Einsatz mit 2 Verzeichnissen auf dem selben Laufwerk optimieren willst, dann solltest du auch mit 2 verschiedenen Verzeichnissen auf dem selben Laufwerk testen. Und wenn du möglichst gute Performance in beiden Fällen haben willst, dann solltest du auch beide testen
So wie du es jetzt machst, also 2x das selbe Verzeichnis lesen, wird halt effektiv nur 1x wirklich vom Laufwerk gelesen. Beim 2. mal Lesen kommen die Daten dann aus dem File Cache - weil's ja das selbe File ist.
-
@hustbaer sagte in Warum klappt Binary bei mir nicht:
weil's ja das selbe File ist
Danke für Deine Erläuterungen. Das ist mir schon klar und in der Anwendung will ich ja damit gesicherte Daten vergleichen, die stehen dann auf einer externen HDD oder evtl. sogar auf eine DVD / Blueray oder einem USB-Stick oder einem Netzlaufwerk.
Weil das Delphi-Programm so deutlich schneller war, wollte ich den Overhead von C# ermitteln, also alles, was mit dem Lesen und auch dem Vergleichen gar nichts zu tun hat, nur der Grundaufwand für das Lesen der Directorys usw.
Deshalb habe ich ja auch Test-Schalter, mit denen ich das Einlesen und Vergleichen überspringen kann.
Das habe ich inzwischen ganz gut hinbekommen, so dass der Unterschied zum Delphi-Programm kaum noch erkennbar ist.
Solche weiteren Optimierungen, wie asynchrones / zeilich paralleles Lesen gibt es bei Delphi 7 nicht. Die neueren Delphi-Versionen können das sicherlich auch.
-
@hustbaer sagte in Warum klappt Binary bei mir nicht:
dann solltest du auch mit 2 verschiedenen Laufwerken testen
Das habe ich jetzt gemacht
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CompHKw - Dateien Vergleichen - (C) 12.12.2022 Hartmut aus Dresden DELPHI Lauf 1 ----------------------------------------------------------------------------------------------------------- Parameter: "V:\#Musik\#MP3-aus-WAV\#TB-MP3" "Z:\#Musik\#MP3-aus-WAV\#TB-MP3" "/U" "/VN" "/F" "/M:200" "/A" ----------------------------------------------------------------------------------------------------------- Vergleich: V:\#Musik\#MP3-aus-WAV\#TB-MP3\ DELPHI Lauf 1 mit: Z:\#Musik\#MP3-aus-WAV\#TB-MP3\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4.880.Datei: V:\#Musik\#MP3-aus-WAV...ger\72-gs-638 Lang Lang ist´s her [Heino].mp3 ================================================================= 246 Unter-Pfade gefunden - identisch. 4.880 Dateien gefunden - und verglichen... 4.880 Dateien verglichen - identisch. Es wurden 25.148.066.175 Bytes = 24.558.658 K-Bytes verglichen Start 18:30:05 Ende 18:34:55 Dauer 00:04:50 ========================================================<Ende>=== Linke MausTaste / ESC = Schließen Rechte MausTaste / F1 = Info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CompHKw - Dateien Vergleichen - (C) 12.12.2022 Hartmut aus Dresden DELPHI Lauf 2 ----------------------------------------------------------------------------------------------------------- Parameter: "V:\#Musik\#MP3-aus-WAV\#TB-MP3" "Z:\#Musik\#MP3-aus-WAV\#TB-MP3" "/U" "/VN" "/F" "/M:200" "/A" ----------------------------------------------------------------------------------------------------------- Vergleich: V:\#Musik\#MP3-aus-WAV\#TB-MP3\ mit: Z:\#Musik\#MP3-aus-WAV\#TB-MP3\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4.880.Datei: V:\#Musik\#MP3-aus-WAV...ger\72-gs-638 Lang Lang ist´s her [Heino].mp3 ================================================================= 246 Unter-Pfade gefunden - identisch. 4.880 Dateien gefunden - und verglichen... 4.880 Dateien verglichen - identisch. Es wurden 25.148.066.175 Bytes = 24.558.658 K-Bytes verglichen Start 18:37:00 Ende 18:42:18 Dauer 00:05:18 ========================================================<Ende>=== Linke MausTaste / ESC = Schließen Rechte MausTaste / F1 = Info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CompCs - Dateien vergleichen - (C) 14.12.2022 Hartmut aus Dresden C# Lauf1 --------------------------------------------------------------- Parameter: V:\#Musik\#MP3-aus-WAV\#TB-MP3 Z:\#Musik\#MP3-aus-WAV\#TB-MP3 --------------------------------------------------------------- Vergleich: V:\#Musik\#MP3-aus-WAV\#TB-MP3\ mit: Z:\#Musik\#MP3-aus-WAV\#TB-MP3\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ============================================================ 246 Unterordner gefunden 4.880 Dateien gefunden - davon 4.880 identische Dateien verglichen. Es wurden 25.148.066.175 Bytes = 24.558.658 K-Bytes verglichen. 18.447 Puffer gelesen, Pufferlänge: 1.572.864 Bytes. Start 18:43:06 Ende 18:44:52 Dauer 00:01:45.6 ===================================================<Ende>=== ESC = Programm beenden ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CompCs - Dateien vergleichen - (C) 14.12.2022 Hartmut aus Dresden C# Lauf2 --------------------------------------------------------------- Parameter: V:\#Musik\#MP3-aus-WAV\#TB-MP3 Z:\#Musik\#MP3-aus-WAV\#TB-MP3 --------------------------------------------------------------- Vergleich: V:\#Musik\#MP3-aus-WAV\#TB-MP3\ mit: Z:\#Musik\#MP3-aus-WAV\#TB-MP3\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ============================================================ 246 Unterordner gefunden 4.880 Dateien gefunden - davon 4.880 identische Dateien verglichen. Es wurden 25.148.066.175 Bytes = 24.558.658 K-Bytes verglichen. 18.447 Puffer gelesen, Pufferlänge: 1.572.864 Bytes. Start 18:45:35 Ende 18:49:15 Dauer 00:03:39.7 statt 9:15 bei C# ALT ===================================================<Ende>=== ESC = Programm beenden ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Die Delphi-Version braucht etwa 5 Minuten, die neue C#-Version 2 bis 3 Minuten und meine alte C# Version über 9 Minuten.
Es werden mp3-Dateien auf einer internen sATA3-HDD mit einer USB3-Sicherungs-HDD verglichen.
-
@hkdd
D.h. das Ding ist jetzt nicht nur gleich schnell, sondern schneller. NiceNoch ein Tip: wenn's um's Lesen von Files geht, spielt ja der File-Cache immer mit rein. Dadurch bekommst du dann unterschiedliche Zeiten je nachdem ob du mit warmem oder kaltem Cache testest. Wenn du nicht für jeden Test den PC rebooten willst, kannst du mit USB HDDs testen. In deinem Fall bräuchtest du halt 2 USB HDDs. Wenn du die vor jedem Test ab- und wieder ansteckst hast du wieder kalte Caches.
-
@hustbaer sagte in Warum klappt Binary bei mir nicht:
spielt ja der File-Cache immer mit rei
Das habe ich mir ja auch gedacht, deshalb habe ich jeweils zweimal das Programm laufen lassen.
Beim Delphi-Programm war der zweite Lauf schneller (warmer Cache).
Beim C# Programm war er allerdings langsamer, als der erste ( überhitzter Cache ??? )