保存流中的二进制数据
问题描述:
使用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();
答
使用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); } } }
请注意,你应该使用以网络响应,响应流和输出流using
报表,以确保他们总是在适当的关闭,像这样:
using (WebResponse response = request.GetResponse())
using (Stream responseStream = response.GetResponseStream())
using (Stream outputStream = File.OpenWrite("map(" + i + ").png"))
{
responseStream.CopyTo(outputStream);
}
+1
Skiiilz :)谢谢 – 2010-12-12 14:38:47
你永远不应该对待任意字节流作为字符串,但。因为他们不是。 – Joey 2010-12-12 14:21:44