踩坑总结:
获取的网络流和普通流不一样,无法直接使用webStream.CopyTo(fileStream)方法,让网络流通过一个已经创建好的文件流保存到本地
using (FileStream file = File.Create(dir + "\\" + name))
{
stream.CopyTo(file);//网络流不能使用copyTo,会报错
}
故尝试读取网络流到byte数组中,再使用byte
再次踩坑:
流好像没办法一次读完,因为此处我设置了非常大的数,但是却只3339(每次打开都是3339,排除网络不稳定可能),打开图片文件也是破损不完整的图片,或许这就是为什么要将流加载到buffer缓冲区读写的原因吧,一次读取并不一定能都到文件流末尾(即使buffer很大),通过stream.Read(buffer, 0, 9999999)放到缓冲区中,只有当返回值为0时才算读完,buffer没满不一定就读完。
ps:有没有大佬解释下为什么流文件不能一次读完至buffer里呀
byte[] buffer = new byte[9999999];
int n = stream.Read(buffer, 0, 9999999); int m = stream.Read(buffer, 0, 9999999);
Console.WriteLine(n);
Console.WriteLine(m);
using (FileStream fsw = new FileStream(dir + "\\" + name, FileMode.OpenOrCreate))
{
fsw.Write(buffer, 0, n);
}
综上想到循环判断 网络流.read()返回值,判断网络流文件是否读完,
**
最终解决方案:
循环判断 网络流.read()返回值,判断网络流文件是否读完,通过FileStream将buffer中的数据写入打开的文件流,直到网络流文件读完(read()返回值为0)
**
byte[] buffer = new byte[1024];
//根据文件地址新建文件流,并通过file.write()写文件
using (FileStream file = File.Create(dir + "\\" + name))
{
int actual;
do
{
actual = stream.Read(buffer, 0, buffer.Length);//返回结果:
//读入缓冲区中的总字节数。 如果很多字节当前不可用,则总字节数可能小于请求的字节数;如果已到达流结尾,则为零 (0)。
//所以只能用是否等于0来判断是否已经读取完成
//将buffer写到文件流
file.Write(buffer, 0, actual);
Console.WriteLine("当前字节数" + actual);
}
while (actual != 0);
Console.WriteLine(file.Length);
}
当然有很多更简单的实现方法,只是我想看看网络流如何直接保存到本地,结果好像就是不能直接保存到本地。。。
ps:如果能请告诉我一下,万分感谢!
其他根据url下载文件的方法:
WebClient下的DownloadFile()方法
using (var client = new WebClient())
{
string dir = Directory.GetCurrentDirectory();
string s = dir + "\\" + cityName + Path.GetFileName(url);
client.DownloadFile(url, s);//下载本地文件
Console.WriteLine(cityName + "图片下载完毕");
}
System.Drawing.Image.FromStream下的Save()方法
保存图片我试过了,其他格式应该也行吧,我没试,试过可行的欢迎留言
System.Drawing.Image downImage = System.Drawing.Image.FromStream(WebRequest.Create(url).GetResponse().GetResponseStream());
string path = dir + "\\" + name;
downImage.Save(path);
downImage.Dispose();