【问题标题】:Download large file in small chunks in C#在 C# 中以小块下载大文件
【发布时间】:2012-11-26 13:54:37
【问题描述】:

我需要下载一些超过 25 MB 的文件,但我的网络只允许请求 25 MB 的文件。

我正在使用以下代码

  const long DefaultSize = 26214400;
    long Chunk = 26214400;
    long offset = 0;
    byte[] bytesInStream;
    public void Download(string url, string filename)
    {
        long size = Size(url);
        int blocksize = Convert.ToInt32(size / DefaultSize);
        int remainder = Convert.ToInt32(size % DefaultSize);
        if (remainder > 0) { blocksize++; }

        FileStream fileStream = File.Create(@"D:\Download TEST\" + filename);
        for (int i = 0; i < blocksize; i++)
        {
            if (i == blocksize - 1)
            {
                Chunk = remainder;

            }

            HttpWebRequest req = (HttpWebRequest)System.Net.WebRequest.Create(url);
            req.Method = "GET";
            req.AddRange(Convert.ToInt32(offset), Convert.ToInt32(Chunk+offset));
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            // StreamReader sr = new StreamReader(resp.GetResponseStream());


            using (Stream responseStream = resp.GetResponseStream())
            {
                bytesInStream = new byte[Chunk];
                responseStream.Read(bytesInStream, 0, (int)bytesInStream.Length);
                // Use FileStream object to write to the specified file
                fileStream.Seek((int)offset, SeekOrigin.Begin);
                fileStream.Write(bytesInStream,0, bytesInStream.Length);
            }
            offset += Chunk;

        }
        fileStream.Close();

    }
    public long Size(string url)
    {
        System.Net.WebRequest req = System.Net.HttpWebRequest.Create(url);
        req.Method = "HEAD";
        System.Net.WebResponse resp = req.GetResponse();
        resp.Close();
        return resp.ContentLength;

    }

它可以在磁盘上正确写入内容,但内容不工作

【问题讨论】:

  • 我无法真正提供答案,但您能单步执行代码吗?我建议缩小所有数字(例如,将最大块大小设置为 10 字节,将下载文件大小设置为 25 字节),然后逐步进行。如果涉及较小的块,可能会更容易发现您出错的地方。
  • 你有没有得到任何最终解决方案,并且 working ?有答案:it still not working你说

标签: asp.net c#-4.0 httpwebrequest websocket


【解决方案1】:

您应该在写入之前检查读取了多少,类似这样(并且您不需要记住要查找的偏移量,写入时查找是自动的):

int read;
do
{
    read = responseStream.Read(bytesInStream, 0, (int)bytesInStream.Length);
    if (read > 0)
        fileStream.Write(bytesInStream, 0, read);
}
while(read > 0);

【讨论】:

    【解决方案2】:

    【讨论】:

      【解决方案3】:

      范围从零开始,您应该从上限中减去 1。

      request.Headers.Range = new System.Net.Http.Headers.RangeHeaderValue(offset, chunkSize + offset - 1);
      

      我在以下链接中发布了正确的代码片段: https://stackoverflow.com/a/48019611/1099716

      【讨论】:

        【解决方案4】:

        Akka 流可以帮助使用多线程从 System.IO.Stream 下载小块文件。 https://getakka.net/articles/intro/what-is-akka.html

        Download 方法会将字节追加到以 long fileStart 开头的文件中。如果文件不存在,fileStart 值必须为 0。

        using Akka.Actor;
        using Akka.IO;
        using Akka.Streams;
        using Akka.Streams.Dsl;
        using Akka.Streams.IO;
        
        private static Sink<ByteString, Task<IOResult>> FileSink(string filename)
        {
            return Flow.Create<ByteString>()
                .ToMaterialized(FileIO.ToFile(new FileInfo(filename), FileMode.Append), Keep.Right);
        }
        
        private async Task Download(string path, Uri uri, long fileStart)
        {
            using (var system = ActorSystem.Create("system"))
            using (var materializer = system.Materializer())
            {
               HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
               request.AddRange(fileStart);
        
               using (WebResponse response = request.GetResponse())
               {
                   Stream stream = response.GetResponseStream();
        
                   await StreamConverters.FromInputStream(() => stream, chunkSize: 1024)
                       .RunWith(FileSink(path), materializer);
               }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2019-01-20
          • 1970-01-01
          • 2011-07-19
          • 1970-01-01
          • 1970-01-01
          • 2012-06-06
          • 2010-10-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多