2

这是我从服务器下载 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];tobyte[] inBuf = new byte[10000000];

该文件正在完美下载。

但我的问题是,如果我下载的文件大于 50 MB(例如:200 MB)。

这种方法不好。

谁能告诉我如何解决这个问题?

4

3 回答 3

3

您可以使用Stream.CopyTo()方法直接从流复制到流。

或者更简单:使用WebClient类及其DownloadFile方法下载文件。此解决方案将取代您的完整方法:

var client = new WebClient();
client.DownloadFile(strURLFileandPath, strFileSaveFileandPath);
于 2012-07-27T12:10:04.077 回答
0

一边读一边写文件。这样,您不必在写入或完成下载之前将所有字节保留在内存中。

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();
于 2012-07-27T12:09:10.663 回答
0

正如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()你的输出。

于 2012-07-27T12:10:13.157 回答