使用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();
答案 0 :(得分:4)
使用StreamReader
/ StreamWriter
肯定是一个错误,是的 - 因为它试图将文件加载为文本,但事实并非如此。
选项:
WebClient.DownloadFile
作为SLaks建议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
来简化当前代码。