本帖最后由 ilovecomputer66 于 2024-7-29 14:20 编辑
这是从URL下载文件的代码
string requestUrl = httpRequest.RequestUri.ToString();
HttpResponseMessage response = null;
try
{
var task = httpClient.SendAsync(httpRequest);
task.Wait();
response = task.Result;
}
catch (AggregateException ex)
{
errorString = $"DoGetForDownloadFile请求超时,异常信息为:\n{ex.ToString()}";
return HttpRequestResultEnum.Timeout;
}
catch (Exception ex)
{
errorString = $"DoGetForDownloadFile请求发生错误,异常信息为:\n{ex.ToString()}";
return HttpRequestResultEnum.OtherError;
}
if (response.IsSuccessStatusCode) 判定为true后,执行下面2种不同写法的代码
[C#] 纯文本查看 复制代码 using (Stream stream = response.Content.ReadAsStreamAsync().Result)
{
using (FileStream fileStream = new FileStream(savePath, FileMode.Create))
{
stream.CopyTo(fileStream);
// 这里需要主动调用,否则在函数return后应该还没有马上释放,立即进行重命名等操作会出问题
fileStream.Close();
}
}
errorString = null;
return HttpRequestResultEnum.Ok;
第二种
[C#] 纯文本查看 复制代码 try
{
Stream stream = response.Content.ReadAsStreamAsync().Result;
FileStream fileStream = new FileStream(savePath, FileMode.Create);
stream.CopyTo(fileStream);
fileStream.Flush();
fileStream.Close();
stream.Flush();
stream.Close();
errorString = null;
return HttpRequestResultEnum.Ok;
}
catch (Exception ex)
{
errorString = $"写入文件发生错误,异常信息为:\n{ex.ToString()}";
return HttpRequestResultEnum.OtherError;
}
我先不说实际表现是否有区别,如果有是什么区别。免得有人根据结果瞎反推原因
懂得大佬请指教下,这两种写法是否相同,是否会引发错误,谢谢
另外我也不明白,以前从课本学到,这样写using,不是退出using块时,会自动释放资源么?结果实测后发现,就是上面注释写的,不手工写那个close,实际就是没释放,导致后续对文件操作比如重命名会失败并报错
(这时很独立的工具类函数,所有变量仅函数内部用到,外面就传入要下载文件的URL和保存到本地的完整路径)
——————————————————————————————————————————————
鉴于目前大家回复到7楼,且全是错误答案,不得已公布实际效果
其实之前,我跟2-7楼一样,因为课本上教的就应该是第一种写法,而且课本上都没有注释那里close一说。讲的都是退出using块,自动释放资源
但是实测,第一种写法是绝对错误的。首先是注释,不手工写close,就是释放不了,不信你自己试试,在using之外,对这个文件操作,比如重命名,就会提示文件被占用。因为根本没释放
而且,第一个代码目前这样,大概率会出现运行出using块后,文件根本没有生成的情况。而第二种写法不会出现此问题
但是我不知道是为什么。但可以保证这个结论是对的,第一种写法大概率是会出问题
|