C#使用恢复(Content-Range)下载文件

3

我们是否拥有一些能够分段下载大文件并在连接失败后恢复下载的 C#库或类?

我已经尝试使用一些内置的WebClient类,但它不支持断点续传下载。

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

出现异常: "从传输流中收到了意外的EOF或0字节"。


如果那个代码出现异常,甚至在尝试处理Content-Range之前就会出现问题。 - Jon Skeet
1个回答

5
我编写了一些有断点续传功能的下载文件代码。
    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;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接