编辑:这是在 Compact Framework 中完成的,我无权访问 WebClient,因此必须使用 HttpWebRequests 完成。
我正在创建一个下载管理器应用程序,它将能够进行并发下载(一次下载多个)并能够报告已完成的百分比并恢复下载。
这意味着我正在将一些字节下载到缓冲区中,然后将缓冲区写入磁盘。我只是想检查为此推荐的算法/过程是什么。
这是我到目前为止的主要下载方法:
private void StartDownload()
{
HttpWebRequest webReq = null;
HttpWebResponse webRes = null;
Stream fileBytes = null;
FileStream saveStream = null;
try
{
webReq = (HttpWebRequest)HttpWebRequest.Create(_url);
webReq.Headers.Add(HttpRequestHeader.Cookie, "somedata");
webRes = (HttpWebResponse)webReq.GetResponse();
byte[] buffer = new byte[4096];
long bytesRead = 0;
long contentLength = webRes.ContentLength;
if (File.Exists(_filePath))
{
bytesRead = new FileInfo(_filePath).Length;
}
fileBytes = webRes.GetResponseStream();
fileBytes.Seek(bytesRead, SeekOrigin.Begin);
saveStream = new FileStream(_filePath, FileMode.Append, FileAccess.Write);
while (bytesRead < contentLength)
{
int read = fileBytes.Read(buffer, 0, 4096);
saveStream.Write(buffer, 0, read);
bytesRead += read;
}
//set download status to complete
//_parent
}
catch
{
if (Thread.CurrentThread.ThreadState != ThreadState.AbortRequested)
{
//Set status to error.
}
}
finally
{
saveStream.Close();
fileBytes.Close();
webRes.Close();
saveStream.Dispose();
fileBytes.Dispose();
saveStream = null;
fileBytes = null;
webRes = null;
webReq = null;
}
}
我应该下载更大的缓冲区吗?我是否应该如此频繁地将缓冲区写入文件(每 4KB 一次?)是否应该有一些线程在其中休眠以确保不会使用所有 CPU?我认为每 4KB 报告进度变化是愚蠢的,所以我计划每下载 64KB 就报告一次。
目前正在寻找一些通用提示或我的代码存在的任何错误。
最佳答案
首先,我会去掉 finally 子句并更改代码以使用“USING”子句。
任何实现 IDisposable 的东西都应该以这种方式编程,以确保垃圾收集正确发生并且在它应该发生的时候发生。
例如:
using (HttpWebRequest webReq = (HttpWebRequest)HttpWebRequest.Create(_url)) {
/* more code here... */
}
其次,我不会在头部用空值实例化我的变量(ala Pascal 风格)。见上例。
第三,下载应该在它自己的线程中进行,该线程与主线程中的回调函数同步以报告状态。将同步调用放在 while 循环的中间。
关于c# - 在 C# 中从 Internet 下载文件并即时写入的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2028886/