.NET
VB.NET: Dateioperationen mit Fortschrittsanzeige Teil 2 – Download von Dateien
Posted on .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 speichertWie 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
Sebastian Gross
http://www.bigbasti.comSebastian Gross arbeitet in Bielefeld als Softwareentwickler für .NET und Java im Bereich Web.Als Fan der .NET-Plattform lässt er sich kein Userguppen Treffen und Community Event im Raum OWL entgehen.Dabei hat er eine besondere Vorliebe für das ASP.NET MVC Framework und für das Test Driven Development (TDD) entwickelt.
Author code snippet
Posted at 17:24 3. Juli 2010.
Hi,
mit DownloadFileAsync geht das noch ein bisschen einfacher. 😉
Der Fortschriitt lässt sich auch über das Event DownloadProgressChanged aktualisieren.
Author admin
Posted at 18:39 3. Juli 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
Author code snippet
Posted at 14:42 4. Juli 2010.
Das stimmt. Ich wollte den Beitrag auch nicht kritisieren, sondern nur eine andere Möglichkeit für die Googler in den Raum werfen. 🙂