Avatar billede zynix Nybegynder
21. november 2005 - 13:35 Der er 22 kommentarer og
1 løsning

download progressbar

jeg er ved at lave en Windows aplication der kan downloade en fil.
her vil jeg gerne ha en progressbar der viser hvor langt downloaden er, lige som den der er når man gemmer en fil via IE.

jeg har følgende kodestykke til at hente filen:
WebClient client = new WebClient();
client.DownloadFile(url, localFile);

er det muligt at udlæse hvor mange bytes der er hentet ud af den samlede filstørelse ?
Avatar billede dr_chaos Nybegynder
21. november 2005 - 13:40 #1
kan du bruge noget i den stil her:

try {
  string imgPath = "http://www.google.com/images/logo.gif";
  HttpWebRequest wRequest = ((HttpWebRequest)(HttpWebRequest.Create(imgPath)));
  WebResponse wResponse = ((WebResponse)(wRequest.GetResponse()));
  FileStream sWriter = new FileStream("new.gif", FileMode.OpenOrCreate);
  int ContentLength = wResponse.ContentLength;
  string sizeInKB = (ContentLength / 1024).ToString();
  this.Text = "The Size of the Image is: " + sizeInKB.Substring(0, sizeInKB.IndexOf(".") + 3) + "KB";
  byte[] buffer = new byte[ContentLength];
  int length = ContentLength;
  int position = 0;
  int complete = 1;
  int returned = 0;
  ProgressBar1.Value = 0;
  ProgressBar1.Maximum = ContentLength;
  while (!(complete == 0)) {
    position = wResponse.GetResponseStream().Read(buffer, returned, length);
    sWriter.Write(buffer, returned, position);
    complete = position;
    returned += position;
    length -= position;
    ProgressBar1.Step = returned;
    ProgressBar1.PerformStep();
  }
  this.Text = "Completed download";
  sWriter.Close();
  wRequest = null;
} catch (Exception ex) {
  Console.WriteLine(ex.Message);
} catch (WebException webex) {
  Console.WriteLine(webex.Message);
}
Avatar billede Slettet bruger
21. november 2005 - 13:41 #2
Det kan du ikke med WebClient class, der er ikke nogle events, som kan give noget information.
Avatar billede dr_chaos Nybegynder
21. november 2005 - 13:51 #3
du kan evt. prøve at tilpasse min kode til dit projekt hvis du vil have størrelsen.
Avatar billede zynix Nybegynder
21. november 2005 - 13:53 #4
dr_chaos:
progressen går bare til "100%" med det samme.
det er som om den regner størelsen af filen forkert fra starten...

kryptos:
har du evt en anden mulighed som kan give mig de events som jeg skal bruge for at tjekke det ?
Avatar billede dr_chaos Nybegynder
21. november 2005 - 13:57 #5
er du sikker på det ikke er fordi filen er downloadet ?
Avatar billede zynix Nybegynder
21. november 2005 - 13:58 #6
ja, hvis jeg kigger i mappen, kan jeg se at fil størrelsen stiger, så downloaden er igang.
Avatar billede driis Nybegynder
21. november 2005 - 13:58 #7
dr_chaos er inde på det rigtige; du skal læse størrelsen først og så løbende se, hvor meget du har hentet. Det er korrekt at WebClient class ikke stiller disse informationer til rådighed.

At progressbar'en går til 100% med det samme kan være at logo.gif ikke fylder ret meget, så første kald til Read returnerer hele filen. Prøv med en større fil. (En anden mulighed er at HttpWebRequest kan finde ud af at tage billedet fra IE's cache).
Avatar billede zynix Nybegynder
21. november 2005 - 14:00 #8
jeg har prøvet med andre filer, og samme resultat.
Avatar billede Slettet bruger
21. november 2005 - 14:02 #9
Nej du skal ud i sådan noget som dr_chaos har vist dig, hvor du henter størrelsen fra contentlength og så selv tæller hvormange bytes du har læst. Problemet med den kode er så vidt jeg lige kan se at bufferen som læses svare til contentlength, derfor vil den læse alle data I et hug i princip skal du læse en byte af gangen, men det kan vise sig at være ineffektivt. BTW hvor store filer taler vi om?
Avatar billede dr_chaos Nybegynder
21. november 2005 - 14:06 #10
måske er denne her mere noget du har brug for.
www.codeproject.com/csharp/webdownload.asp+c%23+webrequest+progressbar&hl=da" target="_blank">http://66.249.93.104/search?q=cache:U6fsmS99NWEJ:www.codeproject.com/csharp/webdownload.asp+c%23+webrequest+progressbar&hl=da
Avatar billede zynix Nybegynder
21. november 2005 - 14:06 #11
egentlig leder jeg efter en universal løsning, det vil sige lige fra 1kb - 700Mb...

hvordan indlæser jeg så pr byte i arrayet ?
og er der en anden løsning som ikke er så "tung" ?
Avatar billede Slettet bruger
21. november 2005 - 14:09 #12
Du kan kalde ReadByte på den stream der returneres ved GetResponseStream på WebResponse objektet.
Avatar billede arne_v Ekspert
21. november 2005 - 14:16 #13
et komplet eksempel:

using System;
using System.Drawing;
using System.IO;
using System.Net;
using System.Windows.Forms;
using System.Threading;

public class MainForm : Form
{
    private ProgressBar bar;
    private Button start;
    private Button abort;
    private Thread t;
   
    public MainForm()
    {
        bar = new ProgressBar();
        start = new Button();
        abort = new Button();
        SuspendLayout();
        bar.Location = new Point(50, 50);
        bar.Size = new Size(200, 50);
        bar.Name = "Progress Bar";
        start.Location = new Point(50,150);
        start.Size = new Size(200, 50);
        start.Name = "Start Button";
        start.Text = "Start";
        start.Click += new EventHandler(StartClick);
        abort.Location = new Point(50,250);
        abort.Size = new Size(200, 50);
        abort.Name = "Abort Button";
        abort.Text = "Abort";
        abort.Click += new EventHandler(AbortClick);
        ClientSize = new Size(300, 350);
        Controls.Add(bar);
        Controls.Add(start);
        Controls.Add(abort);
        Name = "Main Form";
        Text = "Main Form";
        ResumeLayout(false);
    }
    void Reset(int n)
    {
        bar.Minimum = 0;
        bar.Maximum = n;
        bar.Value = 0;
    }
    void Update(int n)
    {
        bar.Value = n;
    }
    delegate void ResetHandler(int n);
    delegate void UpdateHandler(int n);
    void Copy()
    {
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://arne/anonymous/xeve/xeve_bin_axp.zip");
        HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
        int tot = (int)resp.ContentLength;
        if(bar.InvokeRequired)
        {
            bar.Invoke(new ResetHandler(Reset), new object[] { tot });
        }
        else
        {
            Reset(tot);
        }
        Stream f1 = resp.GetResponseStream();
        Stream f2 = new FileStream(@"C:\xeve.zip", FileMode.CreateNew, FileAccess.Write);
        int sofar = 0;
        byte[] b = new byte[1000];
        int n;
        while((n = f1.Read(b, 0, b.Length)) > 0)
        {
            f2.Write(b, 0, n);
            sofar += n;
            if(bar.InvokeRequired)
            {
                bar.Invoke(new UpdateHandler(Update), new object[] { sofar });
            }
            else
            {
                Update(sofar);
            }
        }
        f2.Close();
        f1.Close();
        resp.Close();
    }
    void StartClick(object sender, EventArgs e)
    {
        t = new Thread(new ThreadStart(Copy));
        t.Start();
    }
    void AbortClick(object sender, EventArgs e)
    {
        t.Abort();         
    }
    [STAThread]
    public static void Main(string[] args)
    {
        Application.Run(new MainForm());
        Application.Exit();
        Environment.Exit(0);
    }
}
Avatar billede driis Nybegynder
21. november 2005 - 14:21 #14
Problemet i kodeeksemplet er, at GetResponse er en synkron metode, dvs. den returnerer ikke; før den er færdig med at hente http responset. Du skal bruge de asynkrone versioner, BeginGetResponse osv. Det involverer at du skal lave nogle Callback funktioner som bliver kaldt af .NET frameworket når der er nyt data, osv.
Avatar billede zynix Nybegynder
21. november 2005 - 14:31 #15
mange tak for hjælpen arne_v, vil du være sød at smide et svar...
Avatar billede zynix Nybegynder
21. november 2005 - 14:33 #16
lige inde du svare, har du evt en mulighed for at få KB/sec ud osse ?
eller er det en større opration ?
Avatar billede arne_v Ekspert
21. november 2005 - 15:05 #17
driis>

GetResponse er synkron - den returnerer ikke før web serveren har svaret og
man har fået sine HTTP headerer, men den returnerere inden man henter al
data
Avatar billede arne_v Ekspert
21. november 2005 - 15:06 #18
sofar indeholder antal bytes hentet

hvis du taget tiden ved start og så beregner sofar / (tid nu - tid ved start)

så må det kunne virke
Avatar billede arne_v Ekspert
21. november 2005 - 15:06 #19
og svar
Avatar billede zynix Nybegynder
21. november 2005 - 15:08 #20
mange tak for hjælpen :o)
bare smid et svar arne_v...
Avatar billede arne_v Ekspert
21. november 2005 - 15:11 #21
så må du lige se om du er nødt til det Invoke "#¤"! for at opdatere KB/sec løbende
Avatar billede zynix Nybegynder
21. november 2005 - 15:23 #22
hvad mener du med "#¤"! ?
Avatar billede arne_v Ekspert
21. november 2005 - 15:33 #23
erstat dem med et antal passende eder og forbandelser
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester