C# 文件未完全下载
这是我从服务器下载ZIP文件的C代码。当我下载时,我没有收到文件,但它是部分下载的C# 文件未完全下载,c#,stream,download,C#,Stream,Download,这是我从服务器下载ZIP文件的C代码。当我下载时,我没有收到文件,但它是部分下载的 public static void Download(String strURLFileandPath, String strFileSaveFileandPath) { HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(strURLFileandPath); HttpWebResponse ws = (HttpWebResponse)w
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=新字节[100000]的值时
tobyte[]inBuf=新字节[10000000]代码>
文件正在下载中
但我的问题是,如果我下载的文件大于50MB(例如:200MB)
这种方法不好
有人能告诉我如何解决这个问题吗?边读边写。这样,您就不必在写入或完成下载之前将所有字节都保存在内存中
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();
您可以使用该方法直接从一个流复制到另一个流
或者更简单:使用类及其DownloadFile
方法下载文件。此解决方案将取代您的完整方法:
var client = new WebClient();
client.DownloadFile(strURLFileandPath, strFileSaveFileandPath);
正如fero建议的那样,最好使用Stream.CopyTo()
但是,如果您决定以手动方式将流复制到流(或者将来需要知道如何使用流),则永远不要手动指定缓冲区大小。您通常希望使用无重叠的最大缓冲区大小,以避免过多的内存消耗。对于ResponseStream,您可以为streamreader获取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()
您的输出 您的键盘似乎有相同的问题。:)您的文件大小的标题中没有响应吗downloading@MikhailKozhevnikov我编辑这篇文章是为了反思和澄清,这不是最好的解决方案,只是对他的问题的一个回答。最好的解决方案是copyto方法,避免手动迭代流。感谢重播,但为什么表单没有响应?这是因为下载与UI在同一线程中执行。在下载文件时,用户界面无法处理任何消息。您应该使用该方法并将事件处理程序附加到DownloadFileCompleted
事件,以便知道下载何时完成。请注意,下载方法调用将立即返回。任何需要完整本地文件的代码都必须放在事件处理程序中!谢谢你。我通过后台工作人员解决了这个问题,我希望为此设置一个进度条。网络客户端是否有任何下载进度事件?如果没有,如何设置进度条?为此,您必须使用WebRequest
切换回解决方案。您也不能使用CopyTo
。努内斯帕斯卡尔的答案更适合这里bytesToRead
是缓冲区大小。在每个循环中,最多从请求中读取bytesToRead
字节并写入文件。之后,您可以通过bytesRead
增加进度计数inBuf
必须定义为byte[bytesToRead]
。然后将整个代码放在后台工作程序中。但是请记住,从另一个线程更新UI是相当棘手的(这在stackoverflow上已经讨论了很多)。