c#像.DownloadProgressChanged一样流式传输进度

时间:2013-09-30 14:52:25

标签: c# stream zip webclient

所以我有以下代码:

WebClient webClient = new WebClient();
Stream data = webClient.OpenRead("http://awesomeurl.com/file.zip");
UnzipFromStream(data, @"c:/dir/");

我想在进度条中获得该流的数据,就像您将WebClient与.DownloadProgressChanged

一样使用

但我似乎无法弄清楚如何让它发挥作用......

请注意:我正在使用ICSharpCode.SharpZipLib

更新#1.1

好的,我设法让下面的代码工作(下载和解压缩+显示完整的消息),但进度条没有更新:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        // first, we need to get the exact size (in bytes) of the file we are downloading
        Uri url = new Uri(filename);
        System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
        System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse();
        response.Close();
        // gets the size of the file in bytes
        Int64 iSize = response.ContentLength;

        // keeps track of the total bytes downloaded so we can update the progress bar
        Int64 iRunningByteTotal = 0;

        string outFolder = folder;

        // use the webclient object to download the file
        using (System.Net.WebClient webClient = new WebClient())
        {
            // open the file at the remote URL for reading
            using (System.IO.Stream zipStream = webClient.OpenRead(filename))
            {
                ZipInputStream zipInputStream = new ZipInputStream(zipStream);
                ZipEntry zipEntry = zipInputStream.GetNextEntry();
                while (zipEntry != null)
                {
                    String entryFileName = zipEntry.Name;
                    // to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName);
                    // Optionally match entrynames against a selection list here to skip as desired.
                    // The unpacked length is available in the zipEntry.Size property.

                    // Manipulate the output filename here as desired.
                    String fullZipToPath = Path.Combine(outFolder, entryFileName);
                    string directoryName = Path.GetDirectoryName(fullZipToPath);
                    if (directoryName.Length > 0)
                        Directory.CreateDirectory(directoryName);

                    // Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size
                    // of the file, but does not waste memory.
                    // The "using" will close the stream even if an exception occurs.
                    using (FileStream streamWriter = File.Create(fullZipToPath))
                    {

                        int iByteSize = 0;
                        byte[] buffer = new byte[iSize]; // 4K is optimum

                        StreamUtils.Copy(zipInputStream, streamWriter, buffer);

                        while ((iByteSize = zipStream.Read(buffer, 0, buffer.Length)) > 0)
                        {

                            iRunningByteTotal += iByteSize;

                            // calculate the progress out of a base "100"
                            double dIndex = (double)(iRunningByteTotal);
                            double dTotal = (double)iSize;
                            double dProgressPercentage = (dIndex / dTotal);
                            int iProgressPercentage = (int)(dProgressPercentage * 100);

                            // update the progress bar
                            backgroundWorker1.ReportProgress(iProgressPercentage);
                        }
                    }
                    zipEntry = zipInputStream.GetNextEntry();
                }
            }
        }  
    }

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        progressBar1.Value = e.ProgressPercentage;
    }

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        MessageBox.Show("File download complete");
    }

0 个答案:

没有答案