带简历的C#下载文件(内容范围)

时间:2017-07-05 20:18:13

标签: c# download http-content-range

我们是否有一些C#库或类可以按部件下载大文件,如果连接失败则恢复下载?

我试过使用一些内置的WebClient类,因为它不支持简历下载。

WebClient webClient = new WebClient();
webClient.DownloadFile(link, @"C:\Test\1.zip");

异常失败:"从传输流"收到意外的EOF或0字节。

2 个答案:

答案 0 :(得分:1)

我制作了一些带有简历支持的下载文件的代码。

    static bool DownloadFileWithRange()
    {
        string link = "http://freelistenonline.com/"; //<- link to some big file
        string FilePath = @"C:\Test\1.zip";

        if (File.Exists(FilePath))
            File.Delete(FilePath);

        long totalBytesRead = 0;
        long MaxContentLength = 0;
        long RequestContentLength = 0;
        int i = 0;
        while (MaxContentLength == 0 || totalBytesRead < MaxContentLength)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(link);

            if (totalBytesRead > 0) request.AddRange(totalBytesRead);

            WebResponse response = request.GetResponse();

            Console.WriteLine("=============== Request #{0} ==================", ++i);
            foreach (var header in response.Headers)
            {
                if (header.ToSaveString().Contains("Content-Length") || header.ToSaveString().Contains("Content-Range"))
                    Console.WriteLine("{0}: {1}", header, response.Headers[header.ToString()]);
            }

            if (response.ContentLength > MaxContentLength)
                MaxContentLength = response.ContentLength;             

            var ns = response.GetResponseStream();
            RequestContentLength = 0;
            try
            {
                using (var responseStream = response.GetResponseStream())
                {
                    using (FileStream localFileStream = new FileStream(FilePath, FileMode.Append))
                    {
                        var buffer = new byte[4096];
                        int bytesRead;

                        while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            totalBytesRead += bytesRead;
                            RequestContentLength += bytesRead;
                            localFileStream.Write(buffer, 0, bytesRead);
                        }

                        Console.WriteLine("Got bytes: {0}", RequestContentLength);
                    }

                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Got bytes: {0}", RequestContentLength);
            }
        }

        if (MaxContentLength == totalBytesRead)
            return true;

        return false;
    }

答案 1 :(得分:0)

我意识到这是一篇较旧的帖子,但杜克的回答非常有价值,并想澄清一些观点。我经常参考这篇文章和它的模式。然而,它只能部分恢复,在前五行中,我们通过删除任何先前的进度来切断我们的鼻子。我们已经可以为请求添加一个范围,因此让我们读取现有文件的 FileInfo(FilePath) 并节省宝贵的时间。如果怀疑文件损坏(例如电源故障),您甚至可以将其修剪几个字节以确保文件干净。

同样,使用这个“循环直到”条件可能会以“无限”的噩梦结束。除了此处捕获的一个简单异常之外,部分下载还有许多其他原因。当事情停止时,我遇到了许多 foobar 时刻。当您添加异步模式和并发性时,未知故障不断出现。道德是在循环时尝试总是有一个“出”,直到...

static bool DownloadFileWithRange()
{
    string link = "http://freelistenonline.com/"; //<- link to some big file
    string FilePath = @"C:\Test\1.zip";

    if (File.Exists(FilePath))
        File.Delete(FilePath);

    long totalBytesRead = 0;
    long MaxContentLength = 0;
    long RequestContentLength = 0;
    int i = 0;
    while (MaxContentLength == 0 || totalBytesRead < MaxContentLength)
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(link);

        if (totalBytesRead > 0) request.AddRange(totalBytesRead);

        WebResponse response = request.GetResponse();

        Console.WriteLine("=============== Request #{0} =================="