最近做了一个在线升级的程序,用WebClient做的,再用DownloadFile方法来下载更新文件.问题1,如果用进度条显示下载进度,还有就是如何估算下载时间?问题2,不用进度条也可以,把它弄成像Windows文件复制时,显示的一个文件到另一个文件的图片也可以.但这个动态的图片我在网上没有找到,哪位知道哪里有下载的?
先谢了.

解决方案 »

  1.   

    用BackgroundWorker吧.
    属性
    WorkerReportsProgress = true
    事件
    ProgressChanged += new ProgressChangedEventHandler(Form1.OnProgressChanged);
    DoWork += new DoWorkEventHandler(worker_DoWork);
    实现:
    private void worker_DoWork(object sender, DoWorkEventArgs e)
    {
       你的更新代码.....
    }增加一个显示进度的窗体Form1,摆个进度条progressBar1
    窗体写上此公共方法
    public void OnProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        progressBar1.Value = e.ProgressPercentage;
    }
      

  2.   

    用WebClient的DownloadFile方法如何得到当前的下载量????
      

  3.   

    可以自己绘图做个漂亮的进度条,反正进度条的功能本身就很简单我在使用Remoting的时候是这样确定的:
    首先发送请求,获取文件的总长度
    然后以包为单位向客户端回传数据,每次的量是一样的,即包的大小相同通过这个就能计算出精确进度了
      

  4.   

    to 用WebClient的DownloadFile方法如何得到当前的下载量????这个流量是估算的,例如:
    Stream myStream = myWebClient.OpenRead(uriString);
    byte[] bBuffer = new byte[1024];
    int nRealCount = 0;
    DateTime dtStart;
    TimeSpan ts;
    do
    {
         dtStart = DateTime.Now;
         nRealCount = myStream.Read( bBuffer, 0, bBuffer.Length );
         ts = DateTime.Now - dtStart;
         // 计算流量可以用 nRealCount / ts.Seconds来进行估算
    }
    while( nRealCount > 0 );
      

  5.   

    不过可能1024个字节太少,你可以多做几个循环,然后再去求TimeSpan,这样效果会更好。
      

  6.   

    to Knight94(愚翁)
    不好意思,我真的有点笨,没有理解到你的意思:(
    比如说,我要下载Http://172.16.120.15/DownLoad/abc.rar这个文件,它的大小为12.5M
    用WebClient下载这个文件,并用进度条显示文件的进度和当前下载了多少.
    这个怎么写.我弄了半天都没有弄成功.谢谢了.
      

  7.   

    其实要做模拟,需要知道如下几个数据就可以了:
    1、文件大小:webclient.Headers or webclient.ResponseHeaders来获得;
    2、下载固定长度所耗时间,这我前面已经说明了。
    3、至于已经下载多少数据,可以在“2”的基础上进行累加即可。这样一个进度条所需要的数据都有了。
      

  8.   

    文件的大小肯定可以知道,因为做下载时,文件的大小就放在XML文件里.
    我用DownLoadFile()方法,就是得不到当前的下载量.
    还有就是
    do
    {
         这个是得到当前的时间
         dtStart = DateTime.Now;  
         这个的值一直是1024,因为前面定义的是这么多.
         nRealCount = myStream.Read( bBuffer, 0, bBuffer.Length );
        这个是得到用时多少? 
        ts = DateTime.Now - dtStart;
         // 计算流量可以用 nRealCount / ts.Seconds来进行估算
    }
    while( nRealCount > 0 );
    关键是这个循环有什么用?
      

  9.   

    to 关键是如何得到当前的流量?当前的流量:下载数据大小/下载用时例如: 10k / 2s = 5k/s
      

  10.   

    to while( nRealCount > 0 );
    关键是这个循环有什么用?由于一个文件是分段下载,所以需要循环进行分批获取。
      

  11.   

    大哥,可能是我说错了,
    我的意思是,比如说这外文件,12M,现在下载了2M了,我如何知道当前下载了2M?
      

  12.   

    整个文件12M,现在用了三秒钟了,下载了2M了,
    我如何知道当前下载了2M???
      

  13.   

    接上...
    忘记贴地址了http://community.csdn.net/Expert/TopicView.asp?id=4791058
      

  14.   

    try
    http://www.codeproject.com/csharp/PIEBALDProgressDialog.asp
      

  15.   

    private void DownLoadFile()
            {
                //try
                //{
                    WebClient client = new WebClient();
                    if (!Directory.Exists(Application.StartupPath + @"\temp"))
                    {
                        Directory.CreateDirectory(Application.StartupPath + @"\temp");
                    }
                    for (int i = 0; i <= this.listView1.Items.Count - 1; i++)
                    {
                        string fileName = this.listView1.Items[i].SubItems[0].Text;
                        string url = @"http://172.16.120.155/update/UpdateFile/" + fileName;
                        string file = Application.StartupPath + "\\temp\\" + fileName;
                        this.label2.Text = "正在下载:" + fileName;                    Stream myStream = client.OpenRead(url);
                        byte[] bBuffer = new byte[10240000];
                        int nRealCount = 0;
                        DateTime dtStart;
                        TimeSpan ts;
                        int lenth = Convert.ToInt32(this.listView1.Items[i].SubItems[1].Text.ToString());
                        int k = 0;
                        progressBar1.Value = 0;
                        do
                        {
                            dtStart = DateTime.Now;
                            nRealCount = myStream.Read(bBuffer, 0, bBuffer.Length);
                            ts = DateTime.Now - dtStart;
                            k = k + nRealCount;
                            double pe = ((double)k / (double)lenth) * 100;
                            int va = Convert.ToInt32(pe);
                            progressBar1.Value = va;
                            // 计算流量可以用 nRealCount / ts.Seconds来进行估算
                        }
                        while (nRealCount > 0);
                        FileStream fstr = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write);
                        fstr.Write(bBuffer, 0, k);
                        fstr.Close();                    // client.DownloadFile(url, file);
                        this.listView1.Items[i].SubItems.Add("已下载");
                    }
                    this.progressBar1.Visible = false;
                    this.label2.Text = "正在更新文件,请稍后...";
                    string[] fileDir = Directory.GetFileSystemEntries(Application.StartupPath + @"\temp");                foreach (string str in fileDir)
                    {
                        int pos = str.LastIndexOf(@"\");
                        string FileName = str.Substring(pos);
                        string FilePath = Application.StartupPath + FileName;
                        File.Copy(str, FilePath, true);
                    }                this.label2.Text = "程序更新已完成!";                this.label1.Text = this.finish;
                    this.btnNext.Enabled = false;
                    this.listView1.Visible = false;
                    this.btnExit.Text = "完成(&F)";
                //}
                //catch (Exception errMsg)
                //{
                //    MessageBox.Show(errMsg.Message);
                //}
            }
      

  16.   

    这就是我下载的代码,
    现在进度条是显示出来了,但是问题又出来了,在保存文件的时候就出错了,也就是在这里:
    如果把Buffer设置小了,就会出现问题:
    FileStream fstr = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write);
    fstr.Write(bBuffer, 0, k);
    它提示:
    "偏移量和长度超出数组的界限,或者计数大于从索引到源集合结尾处的元素数量。"还有就是即使有些小文件下载下来了,也打不开,我想问题可能就是出在上面两句.不知道怎么改.
    郁闷.
      

  17.   

    你写的位置不对,应该在循环中去做,一边读一边写,例如:
    do
    {
    dtStart = DateTime.Now;
    nRealCount = myStream.Read(bBuffer, 0, bBuffer.Length);//Read data here
    if( nRealCount > 0 )
      fstr.Write(bBuffer, 0, nRealCount);//Write data here
    ts = DateTime.Now - dtStart;
    k = k + nRealCount;
    double pe = ((double)k / (double)lenth) * 100;
    int va = Convert.ToInt32(pe);
    progressBar1.Value = va;
    // 计算流量可以用 nRealCount / ts.Seconds来进行估算
    }
    while (nRealCount > 0);
      

  18.   

    我就是用 HAVENT(夜雨流星℡) 的办法
      

  19.   

    TO Knight94(愚翁) 
    这个程序,我还有点疑问: nRealCount = myStream.Read( bBuffer, 0, bBuffer.Length );
    1.就是myStream.Read()这个方法,比如说一个文件大小为15000字节,现在我定义一个Buffer为1024,当我们在do循环里用Read()这个方法时,第一次,读了1024字节,再把它写入一个文件,
    当第二次循环时,这个方法怎么知道,从1025开始去文件里读呢? 是不是这个方法会自动判断?还有就是当我把Buffer的值设置得越大,进度条显示的速度越快,这和下载速度没什么关系吧?(我想,可能是我在本机上测试的原因)?最后个问题就是,我基本上每次得到下载的时间都为0(在DO循环里)?
    如果是这样就算不出来下载速度了?因为时间就是为0
      

  20.   

    to 最后个问题就是,我基本上每次得到下载的时间都为0(在DO循环里)?
    如果是这样就算不出来下载速度了?因为时间就是为0因为每次下载的数据量太小,即1k,你可以增大buffer,或者用TimeSpan.Milliseconds 来代替TimeSpan.Seconds
      

  21.   

    to 当第二次循环时,这个方法怎么知道,从1025开始去文件里读呢? 是不是这个方法会自动判断?这个由stream去做,你不用操心了。
    :)
      

  22.   

    如果想了解,参看msdn中stream的read方法
      

  23.   

    我把Buffer加到10240000 ,执行一次这个TS的秒和毫秒的值都为0,算不出来下载速度.
      

  24.   

    可能是我在本机上 下载本机IIS目录里的文件网速太快?
    Thanks
      

  25.   

    我下载一个57M的文件.
    几百KB文件根本测试不出来,进度条一下就走完了.
    下载这个57M的文件,可能花了5秒吧.但测试出来都是0.
    最后,我还在IIS里把流量限制为1K/少,
    结果下载小文件,能看到进度条的显示了,可能要几十秒,但它的值就为0.(在其它机器上运行的程序)
      

  26.   

    change
    double pe = ((double)k / (double)lenth) * 100;with 
    double pe = k;
    pe = pe * 100 / length;
      

  27.   

    private void DownLoadFile()
            {
                try
                {
                    WebClient client = new WebClient();                if (!Directory.Exists(Application.StartupPath + @"\update"))
                    {
                        Directory.CreateDirectory(Application.StartupPath + @"\update");
                    }
                    for (int i = 0; i <= this.listView1.Items.Count - 1; i++)
                    {
                        string fileName = this.listView1.Items[i].SubItems[0].Text;
                        string url = @"http://172.16.120.155/update/UpdateFile/" + fileName;
                        string file = Application.StartupPath + "\\update\\" + fileName;
                        this.label2.Text = "正在下载:" + fileName;                    Stream myStream = client.OpenRead(url);
                        byte[] bBuffer = new byte[102400];
                        int nRealCount = 0;
                        DateTime dtStart;
                        TimeSpan ts;
                        int lenth = Convert.ToInt32(this.listView1.Items[i].SubItems[1].Text.ToString());
                        int cur = 0;
                        progressBar1.Value = 0;
                        FileStream fs = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write);
                        do
                        {
                            dtStart = DateTime.Now;
                            nRealCount = myStream.Read(bBuffer, 0, bBuffer.Length);
                            if (nRealCount > 0)
                            {
                                fs.Write(bBuffer, 0, nRealCount);
                            }
                            ts = DateTime.Now - dtStart;
                            cur = cur + nRealCount;
                           // double pe = ((double)cur / (double)lenth) * 100;
                           // int va = Convert.ToInt32(pe);
                           // progressBar1.Value = va;
                            double pe = cur;
                            pe = pe * 100 / lenth;
                            int va = Convert.ToInt32(pe);
                            progressBar1.Value = va;
                           // this.label2.Text = "正在下载:" + fileName+"   "+cur/1024+" KB/"+lenth/1024+" KB";
                            this.label2.Text = "正在下载:" + fileName + "   " + cur / 1024 + " KB/" + lenth / 1024 + " KB"+"  下载速度:"+nRealCount /ts.Milliseconds  +"kb/s";
                            // 计算流量可以用 nRealCount / ts.Seconds来进行估算
                        }
                        while (nRealCount > 0);
                        fs.Close();
                        // client.DownloadFile(url, file);
                        this.listView1.Items[i].SubItems.Add("已下载");
                    }                this.progressBar1.Visible = false;
                    this.label2.Text = "正在更新文件,请稍后...";
                    string[] fileDir = Directory.GetFileSystemEntries(Application.StartupPath + @"\update");                foreach (string str in fileDir)
                    {
                        int pos = str.LastIndexOf(@"\");
                        string FileName = str.Substring(pos);
                        string FilePath = Application.StartupPath + FileName;
                        File.Copy(str, FilePath, true);
                    }                this.label2.Text = "程序更新已完成!";                this.label1.Text = this.finish;
                    this.btnNext.Enabled = false;
                    this.listView1.Visible = false;
                    this.btnExit.Text = "完成(&F)";
                    step++;
                }
                catch (Exception errMsg)
                {
                    MessageBox.Show(errMsg.Message);
                }
            }
      

  28.   

    每次运行程序,哪个Catch出来的错误每次都说哪个时候间隔为0
      

  29.   

    private void DownLoadFile()
            {
                try
                {
                    WebClient client = new WebClient();                if (!Directory.Exists(Application.StartupPath + @"\update"))
                    {
                        Directory.CreateDirectory(Application.StartupPath + @"\update");
                    }
                    for (int i = 0; i <= this.listView1.Items.Count - 1; i++)
                    {
                        string fileName = this.listView1.Items[i].SubItems[0].Text;
                        string url = @"http://172.16.120.155/update/UpdateFile/" + fileName;
                        string file = Application.StartupPath + "\\update\\" + fileName;
                        this.label2.Text = "正在下载:" + fileName;                    Stream myStream = client.OpenRead(url);
                        byte[] bBuffer = new byte[10240];
                        int nRealCount = 0;
                        DateTime dtStart=DateTime.Now ;
                        TimeSpan ts;
                        int lenth = Convert.ToInt32(this.listView1.Items[i].SubItems[1].Text.ToString());//得到文件大小 单位为字节
                        int cur = 0;
                        progressBar1.Value = 0;
                        FileStream fs = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write);
                        
                        int value=0;//得到下载量
                        int counter = 1;//计算是否读取次数
                        do
                        {
                            if (counter % 10 == 0)//如果读了10次,就算下载速度
                            {
                                ts = DateTime.Now - dtStart;                            int perSecondsValue = (int)((double)value / (ts.TotalMilliseconds / 1000)) / 1024;                          
                                //算出每秒的下载量
                                this.label3.Text = "速度:" +perSecondsValue +" k/s";
                                dtStart = DateTime.Now;
                                value = 0;
                            }                      
                           
                            nRealCount = myStream.Read(bBuffer, 0, bBuffer.Length);
                            if (nRealCount > 0)
                            {
                                fs.Write(bBuffer, 0, nRealCount);
                            }
                            cur = cur + nRealCount;
                            double pe = cur;
                            pe = pe * 100 / lenth;
                            int va = Convert.ToInt32(pe);
                            progressBar1.Value = va;
                            
                            this.label2.Text = "正在下载:" + fileName + "   " + cur / 1024 + " KB/" + lenth / 1024 + " KB";                                  
                            
                            value += nRealCount;
                            counter++;
                        }
                        while (nRealCount > 0);
                        fs.Close();                    
                        // client.DownloadFile(url, file);
                        this.listView1.Items[i].SubItems.Add("已下载");
                    }                this.progressBar1.Visible = false;
                    this.label3.Visible = false;
                    this.label2.Text = "正在更新文件,请稍后...";
                    string[] fileDir = Directory.GetFileSystemEntries(Application.StartupPath + @"\update");                foreach (string str in fileDir)
                    {
                        int pos = str.LastIndexOf(@"\");
                        string FileName = str.Substring(pos);
                        string FilePath = Application.StartupPath + FileName;
                        File.Copy(str, FilePath, true);
                    }                this.label2.Text = "程序更新已完成!";                this.label1.Text = this.finish;
                    this.btnNext.Enabled = false;
                    this.listView1.Visible = false;
                    this.btnExit.Text = "完成(&F)";
                    step++;
                }
                catch (Exception errMsg)
                {
                    MessageBox.Show(errMsg.Message);
                }
            }
      

  30.   

    TO Knight94(愚翁)
    这个程序我今天又把下载的代码改了一下,
    当在DO循环里读取文件有十次时,用十次的下载量除以十次所用时间,就可算出大概的下载速度.但让我不解的是,如查在循环里读一次文件,就算一下速度, 但是有时这个ts.TotalMilliseconds 为0有时又不为0,按理说这个值每次都不应该为0.还有就是,当我把Buffer的值设置得大一些,下载速度也就快一些.
      

  31.   

    to 但让我不解的是,如查在循环里读一次文件,就算一下速度, 但是有时这个ts.TotalMilliseconds 为0有时又不为0,按理说这个值每次都不应该为0.网络状况,已经写硬盘的速度,是不确定的。
      

  32.   

    to 还有就是,当我把Buffer的值设置得大一些,下载速度也就快一些.这有可能,尤其在局域网。