Autor Beitrag
Mindforce
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 358

Win XP Pro / MCE, Win 98, Slax (Linux)
Delphi 07 PRO, Delphi 3+7 (mit Prdx)
BeitragVerfasst: Mi 04.04.12 17:43 
Moin moin,

ich möchte gerne erreichen, dass ich sehen kann, wieviel von X Bytes bereits heruntergeladen worden.
Mein Problem ist, dass ich durch Response.ContentLenght zwar die Länge der Datei ansehen kann (4000 bytes),
jedoch kann ich nicht die aktuelle Position des Downloads abrufen, um zu sehen, wie weit der Download bereits ist.

In einem gesonderten Thread rufe ich folgende Methode auf, um eine Datei durch WebResponse & einem Stream herunterzuladen:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
                HttpWebRequest WebRequestObject = (HttpWebRequest)HttpWebRequest.Create(packIdent[i]);

                WebRequestObject.UserAgent = "Mozilla 4.0/XXXXX";
                WebRequestObject.Referer = "http://google.com";
                WebRequestObject.AllowAutoRedirect = false;

                Response = WebRequestObject.GetResponse();

                Stream WebStream = Response.GetResponseStream();

                FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write);
                ReadWriteStream(WebStream, fs);

                WebStream.Close();
                Response.Close();


Jedoch wenn ich (aus einem anderen Thread) versuche, die aktuelle Position abzufragen mit Response.GetResponseStream().Position
schmeißt er mir eine Exception, in dem er sagt, dass keine Suchläufe erlaubt sein.
> Beim MSDN las ich, dass es evtl. daran liegt, dass die Klasse abgeleitet worden ist und die .Position nicht mitgenommen wurde.

Gibt es eine Lösung bzw. einen anderen Weg einen Datei herunterzuladen und den aktuellen Status anzusehen?

Hoffe ihr könnt helfen.


Mit freundlichen Grüßen,

_________________
Our force; in mind.
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mi 04.04.12 18:26 
Deine Methode ReadWriteStream wird wohl aus dem Response Stream lesen, also kannst du dort doch die Anzahl der bisher gelesenen Bytes mitzählen.

PS: Lokale Variablen werden normalerweise klein geschrieben.

_________________
>λ=
Mindforce Threadstarter
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 358

Win XP Pro / MCE, Win 98, Slax (Linux)
Delphi 07 PRO, Delphi 3+7 (mit Prdx)
BeitragVerfasst: Mi 04.04.12 18:51 
user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
Deine Methode ReadWriteStream wird wohl aus dem Response Stream lesen, also kannst du dort doch die Anzahl der bisher gelesenen Bytes mitzählen.


ReadWriteStream wird natürlich nur dann ausgeführt, wenn der Stream bereits voll beschrieben ist (also nach dem Download). ReadWriteStream ist also unfähig mir den aktuellen Downloadstatus anzuzeigen.

MFG

_________________
Our force; in mind.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4051
Erhaltene Danke: 839

Win7
C++, C# (VS 2015/17)
BeitragVerfasst: Mi 04.04.12 19:09 
Hallo Mindforce,

das Stichwort lautet: asynchrone Datenübertragung.
Schau dir mal den folgenden Artikel dazu an: tomasp.net/blog/csharp-async.aspx (insbesondere die Methode ReadToEndAsync).
Mindforce Threadstarter
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 358

Win XP Pro / MCE, Win 98, Slax (Linux)
Delphi 07 PRO, Delphi 3+7 (mit Prdx)
BeitragVerfasst: Mi 04.04.12 21:27 
Okay, vielen Dank, asynchron war hier das richtige Stichwort.
Ich muss aber ehrlich gestehen mich jetzt schmutzig aus der Affaire gezogen zu haben.
Ich habe die Finger von Sockets & Streams etc. gelassen und mich auf einfache .NET Methoden zurückgezogen.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
        void T_DL() 
        {
            for (int i = 0; i < packIdent.Length; i++)
            {
                WebClient webClient = new WebClient();
                webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
                webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
                webClient.DownloadFileAsync(new Uri(packIdent[i]), path + @"\s."+i.ToString("00"));
            }
        }

        private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            Progress = (int)e.BytesReceived;
        }

        private void Completed(object sender, AsyncCompletedEventArgs e)
        {
            Progressed += Progress;
        }


Mit Threads arbeiten ist im Grunde hierbei garnichtmehr nötig und so ziemlich die einfachste Methode um Dateien herunterzuladen.
Und der Vorteil gegenüber meiner vorherigen Download-Prozedur: Ich kann mehrere Dateien aufeinmal herunterladen und kann somit die volle Bandbreite nutzen (wenn möglich).
Und vor allem wird mein int Progress (global) erhöht, kann ich dann ganz easy auslesen :D

"Gute" Lösung?

MFG

_________________
Our force; in mind.
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Do 05.04.12 00:50 
user profile iconMindforce hat folgendes geschrieben Zum zitierten Posting springen:
ReadWriteStream wird natürlich nur dann ausgeführt, wenn der Stream bereits voll beschrieben ist (also nach dem Download).
Äh, nein. Das ist schließlich der ganze Sinn von Streams.

user profile iconMindforce hat folgendes geschrieben Zum zitierten Posting springen:
"Gute" Lösung?
Wenn dir die Fähigkeiten von WebClient ausreichen, spricht nichts dagegen :) . Aber deine Eventhandler sehen nicht so aus, als ob sie mit parallelen Downloads zurecht kämen?

_________________
>λ=