文件未完全下载 [英] File not downloaded completely

查看:129
本文介绍了文件未完全下载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个从给定的URL下载视频的应用程序。问题是我没有收到整个文件的内容,然后无法播放文件。例如,尝试下载大小为2.23 MB的视频,只给我〜2.11 MB。当我在浏览器中使用URL时,会显示一个对话框来保存视频,并且文件已成功下载。

I am developing an application which downloads videos from a given URL. The problem is that I do not receive the entire file content, then cannot play the file. For example, trying to download a video of size ~2.23 MB, gives me only ~2.11 MB. When I use the URL in a browser it shows me a dialog to save the video and the file is downloaded successfully.

我已尝试使用 WebClient 类,它可以工作,但是我想以块形式下载文件,以便能够报告状态(完成百分比)。以下是我使用的代码:

I have tried using WebClient class and it works, but I want to download the file in chunks in order to be able to report the status(percentage completed). Here is the code I use:

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    int bufferSize = 1024 * 300;
    string filePath = saveFileDialog.FileName;
    if (File.Exists(filePath))
        File.Delete(filePath);
    int totalBytes = 0;
    HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create(DownloadUrl);
    long contentLength = webRequest.GetResponse().ContentLength;
    using (Stream webStream = webRequest.GetResponse().GetResponseStream())
    using (StreamReader reader = new StreamReader(webStream))
    using (BinaryWriter fileWriter = new BinaryWriter(File.Create(filePath)))
    {
        do
        {
            char[] buffer = new char[bufferSize];
            bytesRead = reader.ReadBlock(buffer, 0, bufferSize); // also tried with Read(buffer, 0, bufferSize);
            totalBytes += bytesRead;
            Console.WriteLine("Bytes read: " + bytesRead + " Total Bytes: " + totalBytes + " Content length: " + contentLength);
            if (bytesRead > 0)
                fileWriter.Write(buffer, 0, bytesRead);
        } while (!reader.EndOfStream);
    }
}

我还试图阅读,直到 bytesRead = 0 ,但结果相同。
有没有我缺少的东西?

I have also tried to read until bytesRead = 0, but it's the same result. Is there something that I am missing?

推荐答案

我建议您使用 DownloadFileAsync 。这为您提供了两个事件,可以更轻松地跟踪您的下载进度。

I would recommend that you use DownloadFileAsync instead. This provides you with two events that makes it much easier to track the progress of your download.

DownloadProgressChangedEventHandler

DownloadFileCompleted

简单的实现会像这样。

WebClient client = new WebClient();

client.DownloadProgressChanged += 
        new DownloadProgressChangedEventHandler(DownloadProgressCallback);

client.DownloadFileAsync(DownloadUrl, filePath);

然后有一个更新进度条的功能。

Then have a function that updates your progress bar.

private void DownloadProgressCallback(object sender, 
                                      DownloadProgressChangedEventArgs e)
{
     myProgressBar.Value = e.ProgressPercentage;
}

您还可以访问数据,如 e.BytesReceived e.TotalBytesToReceive

You also have access to data like e.BytesReceived and e.TotalBytesToReceive.

编辑:

我要做的主要改变是将您的缓冲区从 char [] 更改为 byte [] ,然后使用一个Stream而不是StreamReader。

The main change I had to do was to change your buffer from char[] to byte[], and then use a Stream instead of a StreamReader.

我们还检查文件的结尾,检查是否有任何字节写入我们的硬盘驱动器。如果没有留下来写,我们知道我们已经完成了。

We also check the end of file by checking to see if there are any bytes to write to our hard-drive. If there are none left to write, we know that we are done.

private static void download()
{
    int bufferSize = 1024 * 300;
    string filePath = "Test.exe";

    if (File.Exists(filePath))
        File.Delete(filePath);
    int totalBytes = 0;
    HttpWebRequest webRequest =
        (HttpWebRequest)
        HttpWebRequest.Create(
            @"http://www.rarlab.com/rar/wrar420.exe");
    long contentLength = webRequest.GetResponse().ContentLength;
    Console.WriteLine(totalBytes);

    using (WebResponse webResponse = webRequest.GetResponse())
    using (Stream reader = webResponse.GetResponseStream())
    using (BinaryWriter fileWriter = new BinaryWriter(File.Create(filePath)))
    {
        int bytesRead = 0;
        byte[] buffer = new byte[bufferSize];
        do
        {
            bytesRead = reader.Read(buffer, 0, buffer.Length);
            totalBytes += bytesRead;
            fileWriter.Write(buffer, 0, bytesRead);
            Console.WriteLine("BytesRead: " + bytesRead + " -- TotalBytes: " + totalBytes);

        } while (bytesRead > 0);
    }
}

这篇关于文件未完全下载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆