Es gibt mehrere Möglichkeiten:
1.) Du willst am Schluss wissen, wie schnell es war, dann liest du einfach vorher die Länge aus mit new FileInfo(Path).Length und dividierst es durch die vergangene Zeit (vorher und nachher mit DateTime.Now die Zeit auslesen und dann mit Ende.Ticks-Start.Ticks die Zeit ermitteln
2.) Du willst das Ganze laufend haben. Dann machst du zwei FileStreams (einen zum Lesen, einen zum Schreiben mit einer passenden Buffersize (bei Festplatten oder im Netzwerk sind 32-64K ganz in Ordnung, über langsame Internetleitungen etwas weniger (z.B. 4KB)
Dann machst du folgende Schleife (sorry ist VB.NET Code, muss aber in C# genauso gehen):
Dim Pos as Uint64=0
Dim Buffer(Buffersize-1) as Byte
While Pos<InputStream.Length
Dim Gelesen as Integer=InputStream.Read(Buffer,0,Math.Min(Buffer.Length,InputStream.Length-Pos))
OutputStream.Write(Buffer,0,Gelesen)
Pos+=Gelesen
End While
Die Variable Pos kannst du dann in einem Timer auswerten und die Arbeit in einem Thread erledigen. Um das wirst du sowieso nicht herumkommen, weil sonst das GUI einfriert. Den Timer kannst du gleich im Designer reinziehen und doppelklicken (Einschalten nicht vergessen, sonst tut er nicht, entweder im Code .Enabled=True oder gleich im Designer. In dem Timer kannst du dann auch gleich das ganze GUI aktualisieren. Ich schreibe z.B. Ausgaben in eine RTF-Box mit Statusmeldungen nie direkt rein, sondern in eine synchronisierte Queue: Queue.Synchronized(New Queue()
Alle 100ms wird dann alles ausgegeben. Das ist von der Performance auch wesentlich schneller bei vielen Ausgaben weil nicht alle 1ms immer ein Wort angehängt werden muss, sondern nur einmal alle 100m alles in einem Schwung ausgegeben werden kann.
Einen eigenen Thread kannst du so erzeugen:
Dim WorkerThread as new Thread(addressOf(THREAD_Work))
WorkerThread.Priority=Lowest
WorkerThread.Name="Worker"
WorkerThread.isBackground=True
WorkerThread.Start()
Public Sub THREAD_Work(ByVal Parameter as IrgendeineKlasse)
'Deine Kopieroperation
End Sub
3) Wenn du die Geschwindigkeit berechnest, dann solltest du immer auch den Fall abfragen, dass die Zeit 0 ist, wenn diese unter 15ms liegt. Dann dividierst du sonst durch 0.
4) Mit der .NET Kopierfunktion wird nicht aus einer Datei gelesen und in die andere geschrieben, sondern die ganze Datei kopiert mit allen Attributen, die irgendwie dranhängen (Rechte, Änderungsdatum, zusätzliche Dateistreams usw.) Beim Verschieben wird überhaupt nichts gelesen oder geschrieben, sondern auf der selben Partition nur ein Verzeichniseintrag umgehängt. Was schneller ist, kommt immer auf das Betriebssystem an. Bei Vista SP1 ist das Kopieren von großen Dateien optimiert und man wird da nie dran kommen. Bei XP ist man meistens manuell schneller, weil man optimieren kann. Auf einer Platte viel RAM als Cache verwenden, damit die Platte nicht so oft wechseln muss, von einer Platte auf die andere weniger, Cache, damit die Daten in den Write Cache von Windows passen.
1.) Du willst am Schluss wissen, wie schnell es war, dann liest du einfach vorher die Länge aus mit new FileInfo(Path).Length und dividierst es durch die vergangene Zeit (vorher und nachher mit DateTime.Now die Zeit auslesen und dann mit Ende.Ticks-Start.Ticks die Zeit ermitteln
2.) Du willst das Ganze laufend haben. Dann machst du zwei FileStreams (einen zum Lesen, einen zum Schreiben mit einer passenden Buffersize (bei Festplatten oder im Netzwerk sind 32-64K ganz in Ordnung, über langsame Internetleitungen etwas weniger (z.B. 4KB)
Dann machst du folgende Schleife (sorry ist VB.NET Code, muss aber in C# genauso gehen):
Dim Pos as Uint64=0
Dim Buffer(Buffersize-1) as Byte
While Pos<InputStream.Length
Dim Gelesen as Integer=InputStream.Read(Buffer,0,Math.Min(Buffer.Length,InputStream.Length-Pos))
OutputStream.Write(Buffer,0,Gelesen)
Pos+=Gelesen
End While
Die Variable Pos kannst du dann in einem Timer auswerten und die Arbeit in einem Thread erledigen. Um das wirst du sowieso nicht herumkommen, weil sonst das GUI einfriert. Den Timer kannst du gleich im Designer reinziehen und doppelklicken (Einschalten nicht vergessen, sonst tut er nicht, entweder im Code .Enabled=True oder gleich im Designer. In dem Timer kannst du dann auch gleich das ganze GUI aktualisieren. Ich schreibe z.B. Ausgaben in eine RTF-Box mit Statusmeldungen nie direkt rein, sondern in eine synchronisierte Queue: Queue.Synchronized(New Queue()
Alle 100ms wird dann alles ausgegeben. Das ist von der Performance auch wesentlich schneller bei vielen Ausgaben weil nicht alle 1ms immer ein Wort angehängt werden muss, sondern nur einmal alle 100m alles in einem Schwung ausgegeben werden kann.
Einen eigenen Thread kannst du so erzeugen:
Dim WorkerThread as new Thread(addressOf(THREAD_Work))
WorkerThread.Priority=Lowest
WorkerThread.Name="Worker"
WorkerThread.isBackground=True
WorkerThread.Start()
Public Sub THREAD_Work(ByVal Parameter as IrgendeineKlasse)
'Deine Kopieroperation
End Sub
3) Wenn du die Geschwindigkeit berechnest, dann solltest du immer auch den Fall abfragen, dass die Zeit 0 ist, wenn diese unter 15ms liegt. Dann dividierst du sonst durch 0.
4) Mit der .NET Kopierfunktion wird nicht aus einer Datei gelesen und in die andere geschrieben, sondern die ganze Datei kopiert mit allen Attributen, die irgendwie dranhängen (Rechte, Änderungsdatum, zusätzliche Dateistreams usw.) Beim Verschieben wird überhaupt nichts gelesen oder geschrieben, sondern auf der selben Partition nur ein Verzeichniseintrag umgehängt. Was schneller ist, kommt immer auf das Betriebssystem an. Bei Vista SP1 ist das Kopieren von großen Dateien optimiert und man wird da nie dran kommen. Bei XP ist man meistens manuell schneller, weil man optimieren kann. Auf einer Platte viel RAM als Cache verwenden, damit die Platte nicht so oft wechseln muss, von einer Platte auf die andere weniger, Cache, damit die Daten in den Write Cache von Windows passen.
Zuletzt bearbeitet: