保留流中的二进制数据

时间:2010-12-12 14:16:28

标签: c# stream

使用C#,我很惊讶从流中保留二进制信息似乎有多复杂。我正在尝试使用WebRequest类下载PNG数据文件,但只是将生成的Stream传输到文件而不会破坏它比我想象的更冗长。首先,只使用StreamReader和StreamWriter并不好,因为ReadToEnd()函数返回一个字符串,它有效地使PNG文件的大小加倍(可能是由于UTF转换)

所以我的问题是,我真的必须编写所有这些代码,还是有更简洁的方法呢?

            Stream srBytes = webResponse.GetResponseStream();
            // Write to file
            Stream swBytes = new FileStream("map(" + i.ToString() + ").png",FileMode.Create,FileAccess.Write);
            int count = 0;
            byte[] buffer = new byte[4096];
            do
            {
                count = srBytes.Read(buffer, 0, buffer.Length);
                swBytes.Write(buffer, 0, count);
            }
            while (count != 0);
            swBytes.Close();

2 个答案:

答案 0 :(得分:4)

使用StreamReader / StreamWriter肯定是一个错误,是的 - 因为它试图将文件加载为文本,但事实并非如此。

选项:

  • 使用WebClient.DownloadFile作为SLaks建议
  • 在.NET 4中,使用Stream.CopyTo(Stream)以与此处相同的方式复制数据
  • 否则,编写自己的实用工具方法进行复制,然后只需要执行一次;您甚至可以将其作为扩展方法编写,这意味着当您升级到.NET 4时,您可以摆脱实用程序方法并使用内置的方法而不更改调用代码:

    public static class StreamExtensions
    {
        public static void CopyTo(this Stream source, Stream destination)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (destination == null)
            {
                throw new ArgumentNullException("destination");
            }
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0)
            {
                destination.Write(buffer, 0, bytesRead);
            }
        }
    }
    

请注意,您应该对Web响应,响应流和输出流使用using语句,以确保它们始终正确关闭,如下所示:

using (WebResponse response = request.GetResponse())
using (Stream responseStream = response.GetResponseStream())
using (Stream outputStream = File.OpenWrite("map(" + i + ").png"))
{
    responseStream.CopyTo(outputStream);
}

答案 1 :(得分:3)

您可以拨打WebClient.DownloadFile(url, localPath)

在.Net 4.0中,您可以通过调用Stream.CopyTo来简化当前代码。