这是我从服务器下载ZIP文件的C#代码。当我下载时,我没有收到文件,但它是部分下载的。
public static void Download(String strURLFileandPath, String strFileSaveFileandPath)
{
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(strURLFileandPath);
HttpWebResponse ws = (HttpWebResponse)wr.GetResponse();
Stream str = ws.GetResponseStream();
byte[] inBuf = new byte[100000];
int bytesToRead = (int)inBuf.Length;
int bytesRead = 0;
while (bytesToRead > 0)
{
int n = str.Read(inBuf, bytesRead, bytesToRead);
if (n == 0)
break;
bytesRead += n;
bytesToRead -= n;
}
try
{
FileStream fstr = new FileStream(strFileSaveFileandPath, FileMode.OpenOrCreate, FileAccess.Write);
fstr.Write(inBuf, 0, bytesRead);
str.Close();
fstr.Close();
}
catch (Exception e) {
MessageBox.Show(e.Message);
}
}
我认为问题发生在这里
byte[] inBuf = new byte[100000];
当我将byte[] inBuf = new byte[100000];
的值增加到byte[] inBuf = new byte[10000000];
时
这个文件下载得很好。
但我的问题是,如果我下载的文件大于50MB(例如:200MB)。
这种方法不好。
有人能告诉我如何解决这个问题吗?
您可以使用stream.CopyTo()方法直接从流复制到流。
或者更简单:使用WebClient类及其DownloadFile
方法下载文件。此解决方案将取代您的完整方法:
var client = new WebClient();
client.DownloadFile(strURLFileandPath, strFileSaveFileandPath);
边读边写文件。这样,在编写或完成下载之前,就不必将所有字节都保存在内存中。
FileStream fstr = new FileStream(strFileSaveFileandPath, FileMode.OpenOrCreate, FileAccess.Write);
int bytesRead;
do
{
bytesRead = str.Read(inBuf, 0, bytesToRead);
fstr.Write(inBuf, 0, bytesRead);
}while (bytesToRead > 0);
str.Close();
fstr.Close();
正如fero建议的那样,最好使用Stream.CopyTo()
但是,如果您决定以手动方式复制流(或者需要知道将来如何使用流),则永远不应该手动指定缓冲区大小。您通常希望使用没有重叠的最大缓冲区大小,以避免过度的内存消耗,在ResponseSream的情况下,您可以为流读取器获得ContentLength
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(strURLFileandPath);
HttpWebResponse ws = (HttpWebResponse)wr.GetResponse();
Stream str = ws.GetResponseStream();
byte[] inBuf = new byte[str.ContentLength];
int bytesToRead = (int)inBuf.Length;
还要记住并Flush()
您的输出。