Benutzer mit den meisten Antworten
Kuriosität bei Lese und Schreibzugriff auf USB-Laufwerk

Frage
-
Hallo,
Ich hoffe, dass mir hier jemand den entscheidenden Tipp geben kann.
Anbei ein Programmausschnitt, der Schreibgeschwindigkeit, Lesegeschwindigkeit und Fehler auf einem Laufwerk finden soll.
Das Problem ist: das beschreiben funktioniert einwandfrei. Schreibgeschwindigkeit stimmt.
Das lesen funktioniert aber nicht richtig, will heißen, geht viel zu schnell. Nur wenn ich das Programm beende und beim nächsten Mal nur lese stimmt die Lesegeschwindigkeit. Das Programm stellt hier also irgendeinen Zusammenhang zwischen dem Lese und Schreibarry her. Das kuriose ist, selbst, wenn das geschriebene Array auf dem Datenträger nicht mit dem zu schreibenden Array übereinstimmt (weil Sektoren Kaput sind) liest das Programm das richtige Array ein (bzw. speichert das Richtige Array im Lesepuffer)
Hier findet wohl irgendeine ungewollte Codeoptimierung statt! Kann mir jemand sagen wie ich das lösen kann? Bzw. hat irgendwer eine Idee? (Ich brauche nicht erwähnen, dass ich schon gefühlt alles ausprobiert habe)
Module Module1 Public Function LaufwerkPruefen(Pfad As String) As Boolean Dim Startzeit As Date Dim Schreibgeschwindigkeit, Lesegeschwindigkeit As Double Dim Dateigrösse As Double = 1024 * 1024 * 50 '50MB Dim SchreibBytes(Dateigrösse) As Byte 'Bytes die geschrieben werden sollen Dim LeseBytes(Dateigrösse) As Byte 'Bytes die gelesen werden sollen 'Mit zufallszahlen füllen um es dem USB-Stick schwieriger zu machen Dim R As New System.Random R.NextBytes(SchreibBytes) 'Beschreiben Startzeit = Now My.Computer.FileSystem.WriteAllBytes(Pfad & "\test" & ".ABC", SchreibBytes, False) Schreibgeschwindigkeit = Dateigrösse / (1024 ^ 2) / (CInt(System.DateTime.Now.Subtract(Startzeit).TotalMilliseconds)) * 1000 'Lesen Startzeit = Now LeseBytes = IO.File.ReadAllBytes(Pfad & "\test" & ".ABC") Lesegeschwindigkeit = Dateigrösse / (1024 ^ 2) / (CInt(System.DateTime.Now.Subtract(Startzeit).TotalMilliseconds)) * 1000 'Prüfen For i As Integer = 0 To SchreibBytes.Length - 1 If Not (SchreibBytes(i) = LeseBytes(i)) Then ' Byte-Element sind unterschiedlich! Return False End If Next Return True End Function End Module
Antworten
-
Hallo,
mit High-Level Routinen wie sie von .NET verwendet werden, kann man die Performance nicht realistisch messen. Da beeinflussen u. a. die Windows Caches Messergebnisse zu stark.
Schau Dir mal an: http://www.heise.de/download/h2testw.html
Gruß Elmar
- Als Antwort vorgeschlagen Tom Lambert (Koopakiller)Moderator Sonntag, 25. August 2013 14:01
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Mittwoch, 28. Januar 2015 07:30
-
Hallo,
fehlerhafte Sektoren kannst Du so schon mal gar nicht erkennen. Erkennt Windows, dass ein Zugriff aus dem Cache erfolgen kann, so greift es erst gar nicht auf den USB Stick zu.
Um ein direktes Schreiben zu erzwingen müsste man die FileOption.WriteThrough verwenden.
Funktionieren kann das bestenfalls, wenn Du den USB Stick einmal auswirfst, damit der Cache als ungültig erklärt wird. Auch dann können Dinge wie das Verlagern von defekten Sektoren das Ergebnis verfälschen.
Wirklich zuverlässige Ergebnisse gibt es nur, wenn man den Cache umgeht, aber auch Treiber Einstellungen können es beeinflussen - so sind - wurde mal in der C't behandelt - diverse Sticks zu finden, die bei der Kapazität lügen.
Das geht aber nur mit Low-Level Zugriffen (und hier auch technischen Kenntnisse über den Aufbau von USB Sticks). Dies kann man in .NET alleine jedoch nicht programmieren.
Gruß Elmar
- Als Antwort vorgeschlagen Tom Lambert (Koopakiller)Moderator Sonntag, 25. August 2013 14:02
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Mittwoch, 28. Januar 2015 07:32
Alle Antworten
-
Hallo,
ich denke mal das da die Code-Optimierung dazwischen geht. Das geht ggf. in den Projekteigenschaften unter Kompilieren > Erweiterte Kompilierungsoptionen zu deaktivieren.
Ich habe deinen Code nur ohne Optimierung getestet. Da gab es keine Zeitlich-Großen unterschiede.
PS: Gehe bitte vom My-Namnespace weg. Zum Schreiben/Lesen von Dateien nutze bitte die entsprechenden Streams oder die File-Klasse.
PPS: Zum Zeit stoppen: http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx
<Code:13/> - Koopakiller [kuːpakɪllɐ]
Webseite | Code Beispiele | Facebook | Snippets
Wenn die Frage beantwortet ist, dann markiert die hilfreichsten Beiträge als Antwort und bewertet die Beiträge. Danke.
Einen Konverter zwischen C# und VB.NET Code gibt es hier. -
Danke schon mal für den TIPP
- Projekt->[Name] Eigenschaften->Kompilieren->Erweiterte Kompilierungsoptionen-> Optimierung aktivieren ist nicht gesetzt, da ich das auch schon vermutet hatte!
- Stopwatch ist wahrscheinlich wirklich besser aber, das ist leider nicht das Problem. Dennoch ein guter Tipp
Die 50 Mb sind natürlich nur für einen sehr langsamen USB Stick (ca. 1,7 Mb/s) d.h. bei einem schnelleren, sollte man eventuell ein Größeres Array definieren, um das Problem erfassen zu können.
-
Hallo,
mit High-Level Routinen wie sie von .NET verwendet werden, kann man die Performance nicht realistisch messen. Da beeinflussen u. a. die Windows Caches Messergebnisse zu stark.
Schau Dir mal an: http://www.heise.de/download/h2testw.html
Gruß Elmar
- Als Antwort vorgeschlagen Tom Lambert (Koopakiller)Moderator Sonntag, 25. August 2013 14:01
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Mittwoch, 28. Januar 2015 07:30
-
Hallo das Tool ist mir bekannt! Hilft mir aber nicht!
Mich interessiert gar nicht wirklich die Schreibgeschwindigkeit als vielmehr fehlerhafte Sektoren! Diese werden aber auch nicht erkannt, da das zweite Array mit den Daten befüllt wird die logischerweise drin seien müssten und nicht denen, die bei fehlerhaften Sektoren wirklich drin sind!
Das Programm sagt immer Schreibbytes = Lesebytes selbst wenn dem nicht so ist! Weil es ja eigentlich so seinen sollte.
-
Hallo,
fehlerhafte Sektoren kannst Du so schon mal gar nicht erkennen. Erkennt Windows, dass ein Zugriff aus dem Cache erfolgen kann, so greift es erst gar nicht auf den USB Stick zu.
Um ein direktes Schreiben zu erzwingen müsste man die FileOption.WriteThrough verwenden.
Funktionieren kann das bestenfalls, wenn Du den USB Stick einmal auswirfst, damit der Cache als ungültig erklärt wird. Auch dann können Dinge wie das Verlagern von defekten Sektoren das Ergebnis verfälschen.
Wirklich zuverlässige Ergebnisse gibt es nur, wenn man den Cache umgeht, aber auch Treiber Einstellungen können es beeinflussen - so sind - wurde mal in der C't behandelt - diverse Sticks zu finden, die bei der Kapazität lügen.
Das geht aber nur mit Low-Level Zugriffen (und hier auch technischen Kenntnisse über den Aufbau von USB Sticks). Dies kann man in .NET alleine jedoch nicht programmieren.
Gruß Elmar
- Als Antwort vorgeschlagen Tom Lambert (Koopakiller)Moderator Sonntag, 25. August 2013 14:02
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Mittwoch, 28. Januar 2015 07:32