提问人:Ashutosh Pandey 提问时间:11/17/2023 最后编辑:Svyatoslav DanylivAshutosh Pandey 更新时间:11/17/2023 访问量:98
高效下载大文件
Download Large File Efficiently
问:
我编写了以下方法来下载文件并保存在 c# 中。.net framework 4.7.2
public static bool DownloadFiles(Uri url, string filePath)
{
try
{
using (HttpClient client = new HttpClient())
{
using (var stream = client.GetStreamAsync(url))
{
using (var fs = new FileStream(filePath, FileMode.OpenOrCreate))
{
stream.Result.CopyTo(fs);
}
}
}
return true;
}
catch (Exception ex)
{
return false;
}
}
上面的代码对于大文件是有效的,我试图做一些性能分析,但没有得出一些明确的结论。我是 C# 的新手,因为它不是我的主要技术堆栈,任何建议都会非常有帮助。
答:
3赞
Svyatoslav Danyliv
11/17/2023
#1
此函数应为异步函数。 不应释放 从 .NET 客户端调用 Web API (C#):HttpClient
public static class HttpUtils
{
static HttpClient client = new HttpClient();
public static async Task<bool> DownloadFilesAsync(Uri url, string filePath)
{
try
{
using (var stream = await client.GetStreamAsync(url))
{
using (var fs = new FileStream(filePath, FileMode.OpenOrCreate))
{
await stream.CopyToAsync(fs);
}
}
return true;
}
catch (Exception ex)
{
return false;
}
}
}
评论
0赞
Ashutosh Pandey
11/17/2023
感谢您的回复,此流是否以块形式获取,这会导致内存问题吗?client.GetStreamAsync(url)
0赞
Svyatoslav Danyliv
11/17/2023
是的,它是按块复制的。
0赞
Svyatoslav Danyliv
11/17/2023
CopyToAsync
如果要配置缓冲区大小,也要重载。
1赞
Amit Mohanty
11/17/2023
#2
为了获得更好的性能,可以进行一些改进和考虑。
GetStreamAsync
是一个异步方法,它返回 . 您应该使用它来获取实际流。Task<Stream>
await
- 对于大文件,使用 可能会消耗大量内存。
请考虑使用缓冲区从源流中读取数据块
并将它们写入目标流。
CopyTo
public static async Task<bool> DownloadFiles(Uri url, string filePath)
{
try
{
using (HttpClient client = new HttpClient())
{
using (Stream stream = await client.GetStreamAsync(url))
{
using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate))
{
byte[] buffer = new byte[8192]; // 8KB buffer (can adjust size)
int bytesRead;
while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
await fs.WriteAsync(buffer, 0, bytesRead);
}
}
}
}
return true;
}
catch (Exception ex)
{
// Handle exceptions appropriately (log, notify, etc.)
Console.WriteLine(ex.Message);
return false;
}
}
评论
1赞
Magnus
11/17/2023
CopyTo 使用缓冲区,您甚至可以指定大小。
评论