【问题标题】:ReadAsync get data from bufferReadAsync 从缓冲区获取数据
【发布时间】:2014-08-03 22:18:40
【问题描述】:

一段时间以来,我一直在琢磨这个问题(并且知道这很愚蠢)。

我正在下载带有显示正常的 ProgressBar 的文件,但是如何从 ReadAsync 流中获取数据以保存?

public static readonly int BufferSize = 4096;
int receivedBytes = 0;
int totalBytes = 0;
WebClient client = new WebClient();
byte[] result;

using (var stream = await client.OpenReadTaskAsync(urlToDownload))
{
  byte[] buffer = new byte[BufferSize];
  totalBytes = Int32.Parse(client.ResponseHeaders[HttpResponseHeader.ContentLength]);

  for (;;)
  {
    result = new byte[stream.Length];
    int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
    if (bytesRead == 0)
    {
      await Task.Yield();
      break;
    }

    receivedBytes += bytesRead;
    if (progessReporter != null)
    {
      DownloadBytesProgress args = 
                 new DownloadBytesProgress(urlToDownload, receivedBytes, totalBytes);
      progessReporter.Report(args);
    }
  }
}

我尝试通过结果变量,但这显然是错误的。在这个漫长的周日下午,我将不胜感激。

【问题讨论】:

  • 我认为您需要另一个流来将文件(缓冲区)保存到磁盘。
  • 你的缓冲区的内容是什么?内容在您的byte[] buffer 变量中
  • 好吧,你没有使用resultresult 不可能包含您的数据,因为流甚至不知道该变量的存在。 (我感觉你在这里有一些误解。不确定是什么。)
  • 是的。它会创建一个长度正确的文件,其中没有数据。

标签: c#


【解决方案1】:

下载的内容在您的 byte[] buffer 变量中:

int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);

来自Stream.ReadAsync

缓冲区:

类型:System.Byte[] 要将数据写入的缓冲区。

您根本不会使用您的 result 变量。不知道为什么它在那里。

编辑

所以问题是如何阅读流的全部内容。您可以执行以下操作:

public static readonly int BufferSize = 4096;
int receivedBytes = 0;
WebClient client = new WebClient();

using (var stream = await client.OpenReadTaskAsync(urlToDownload))
using (MemoryStream ms = new MemoryStream())
{
    var buffer = new byte[BufferSize];
    int read = 0;
    totalBytes = Int32.Parse(client.ResponseHeaders[HttpResponseHeader.ContentLength]);

    while ((read = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
    {
        ms.Write(buffer, 0, read);

        receivedBytes += read;
        if (progessReporter != null)
        {
           DownloadBytesProgress args = 
             new DownloadBytesProgress(urlToDownload, receivedBytes, totalBytes);

           progessReporter.Report(args);
         }
    }
    return ms.ToArray();
  }
}

【讨论】:

  • 感谢 Yuzal,但我的缓冲区限制为 4096 字节。
  • 嗯?但那是您放入 ReadAsync 方法中的缓冲区。
  • 我试图以小块的形式显示完成百分比。
  • 我很困惑,你问你的数据在哪里,你把你的buffer 变量传递给ReadAsync。我对你在问什么感到困惑
  • 非常感谢,尤瓦尔。这可以正常工作。非常感谢!
【解决方案2】:

您读取的数据应该在buffer 数组中。实际上是数组的开头bytesRead 字节。查看 MSDN 上的ReadAsync 方法。

【讨论】:

  • 感谢 Gildor,我认为问题在于我将缓冲区大小限制为 4096
  • @JohnSourcer 然后您应该从流中获取前 4096 个字节。是这样吗?
  • 是的。但是我需要肯定地添加下一个块(直到完成)。为了得到整个流。
  • @JohnSourcer 是的。实际上,我认为您应该在问题中提及(您已经获得了最初的 4096 个字节),以便人们可以真正帮助您。不管怎样,你自己想出来了很好!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-02
  • 1970-01-01
  • 2019-05-04
  • 1970-01-01
  • 2017-11-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多