VB.NET: Dateioperationen mit Fortschrittsanzeige Teil 2 – Download von Dateien
Wenn man grafische Oberflächen entwickelt wird man irgendwann an dem Punkt kommen wo man Dateien kopieren, verschieben oder herunterladen will. Wenn diese nicht grade wenig und klein sind bietet es sich natürlich an eine Fortschrittanzeige dafür zu erstellen. Damit wird sich diese Serie beschäftigen.
Teil 2 - Download von Dateien
Im letzten Teil haben wir gesehen, wie man beim Kopieren von Dateien einen Fortschrittsbalken erzeugt, nun wollen wir das ganze für ein Download Programm umsetzen.
Wer sich schon mal im My-Namespace umgeschaut hat wird sicherlich die Funktion DownloadFile() entdeckt haben. Diese Funktion erleichtert uns das Leben sehr, da diese uns erlaubt mit nur einer Zeile Code eine Datei aus dem Internet zu laden.
Das blöde daran ist, dass wenn die Datei etwas größer ist blockiert der Download den Ganzen Thread sodass dieser nicht mehr reagiert bis der Download abgeschlossen ist! Dies wollen wir ändern und den Downloadvorgang visualisieren.
Das werden wir so ähnlich gestalten, wie in Teil eins, nur etwas Anfängerfreundlicher. (Ich habe gemerkt dass das Beispiel aus Teil 1 doch nicht so das Gelbe vom Eis ist!)
Das Vorgehen dabei ist aber fast das gleiche. Wir erstellen einen Stream zu der Datei die wir herunterladen wollen und einen Stream zu einer Lokalen Datei in die wir die gelesenen Bytes speichern. Klingt doch ganz easy oder?
Dabei werden wir folgende Variablen benutzen:
Dim timer As Stopwatch 'Stoppuhr zur bestimmung der Downloadgeschwindigkeit
Dim loaded As Long 'Anzahl na Bytes die in einer Zeiteinheit geladen wurden
Dim speed As Double 'Downloadgeschwindigkeit in KB/s
Dim url As String 'Die URL mit der zu ladenden Datei
Dim des As String 'Zielpfad auf dem lokalen System
Dim buffer(32768) As Byte 'Puffer für den Download -> Je größer desto schneller der Download
Dim totBytes As Long 'Größe der zu ladenden Datei
Dim curBytes As Long 'Bisher geladene Bytes
Dim readBytes As Long 'Anzehl gelesener Bytes pro Block
Dim bis As BinaryReader 'Der Strom mit der zu ladenden Datei
Dim fos As FileStream 'Strom der die Datei lokal speichert
Wie man sieht findet man hier nichts ungewöhnliches. Das einzige, dass neu ist ist die Stopwatch-Variable. Diese benötigen wir später um die Downloadgeschwindigkeit zu ermitteln.
timer = New Stopwatch
'Stream zur Datei im Internet erstellen und Lokal
Dim request As HttpWebRequest = HttpWebRequest.Create(url)
Dim response As HttpWebResponse = request.GetResponse
bis = New BinaryReader(response.GetResponseStream)
fos = New FileStream(des, FileMode.Create, FileAccess.Write)
totBytes = response.ContentLength
timer.Start() 'Mit dem Timer messen wir, wieviele Bytes in der letzten Sekunde heruntergeladen wurden
While (True)
readBytes = bis.Read(buffer, 0, buffer.Length) 'Aus dem Download Stream lesen
If readBytes = 0 Then
Exit While 'Download ist abgeschlossen
End If
fos.Write(buffer, 0, readBytes) 'Geladene Bytes lokal Speichern
curBytes += readBytes 'Anzahl gesammt gelesener Bytes erhöhen
loaded += readBytes 'Anzahl der Bytes erhöhen die in der Letzten Sekunde geladen wurden
If timer.ElapsedMilliseconds >= 1000 Then 'Wenn eine Sekunde vergangen ist
speed = 0
speed = FormatNumber(loaded / 1024, 2) 'Geschwindigkeit berechnen
loaded = 0 'und zähler zurücksetzen
timer.Reset() 'den Timer neustarten
timer.Start()
End If
'Die Anzeige im Formular-Thread aktualisieren
Label1.Invoke(New refreshGUIDel(AddressOf refreshGUI), New Object() {})
End While
'Ressourcen Freigeben
timer.Stop()
fos.Close()
bis.Close()
Kommen wir zu dem Kernunterschied. Hier kopieren wir Daten von einem Fremden Rechner (Server) zu dem wir ersteinmal eine Verbindung benötigen! Diese Verbindung können wir mit Hilfe eines HttpWebRequests (Eine Anfrage an den Server) herstellen. Und von dem bekommen wir dann auch eine Antwort in Form eines HttpWebResponse welcher uns dann auch einen Strom zu der angefragten Datei liefert!
Nun folgt der eigentliche Downloadvorgang. Wir lesen den Strom blöckchenweise und speichern ihn auch "gleichzeitig" ab. Da wir wissen wieviele Bytes übertragen wurden können wir auch einen Fortschritt anzeigen und auch die Geschwindigkeit berechnen.
Hier hat sich im Vergleich zu Teil 1 nicht viel getan. Neu ist die Stopwarch die nach jeweils einer Sekunde die Geschwindigkeit berechnet indem es misst wieviele Bytes in der letzten Sekunde übertragen wurden!
Bild 1: Das Downloadprogramm in Aktion
Heraus kommt ein kleines Tool, das eine beliebige Datei herunterladen kann und uns währenddessen mit ein paar Informationen versorgt.
Wie üblich gibts hier das Demoprojekt: Download
Habt ihr Tipps oder Fragen? Zögert nicht und schreibt einen Kommentar oder Mail!
Teil 1 - Kopieren und Verschieben von Dateien
Teil 2 - Download von Dateien
Teil 3 - Wiederaufnahme von Downloads nach einem Abbruch
Teil 4 - Upload von Dateien
Juli 3rd, 2010
Hi,
mit DownloadFileAsync geht das noch ein bisschen einfacher.
Der Fortschriitt lässt sich auch über das Event DownloadProgressChanged aktualisieren.
Juli 3rd, 2010
Hallo, vollkommen richtig. Es gibt natürlich viele Wege die nach Rom führen
Allerdings dürfede es dann Probleme geben wenn mann Downloads wiederaufnehmen will oder die geladenen Bytes verarbeiten will. mfg, basti
Juli 4th, 2010
Das stimmt. Ich wollte den Beitrag auch nicht kritisieren, sondern nur eine andere Möglichkeit für die Googler in den Raum werfen.