[英]How to change this code to download file bigger than 2GB?
我正在使用此代碼,適用於較小的文件,但無法下載文件大小超過2GB的文件。 我也嘗試過使用webclient ,但是它不適合我的代碼或無法正常工作,因為此代碼可以正常工作,只是試圖弄清楚如何使用此客戶端下載2GB文件。 謝謝
System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url_);
//request.Proxy = WebRequest.GetSystemWebProxy();
System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse();
ServicePoint sp = request.ServicePoint;
sp.ConnectionLimit = MAX_THREADS;
response.Close();
// gets the size of the file in bytes
Int64 iSize = response.ContentLength;
// keeps track of the total bytes downloaded so we can update the progress bar
Int64 iRunningByteTotal = 0;
UpdateStatus("File OK", count);
// use the webclient object to download the file
using (System.Net.WebClient client = new System.Net.WebClient())
{
// open the file at the remote URL for reading
using (System.IO.Stream streamRemote = client.OpenRead(new Uri(VideoUrl)))
{
// using the FileStream object, we can write the downloaded bytes to the file system
using (Stream streamLocal = new FileStream(sFilePathToWriteFileTo, FileMode.Create, FileAccess.Write, FileShare.None))
{
// loop the stream and get the file into the byte buffer
int iByteSize = 0;
byte[] byteBuffer = new byte[iSize];<---------throws error here
while ((iByteSize = streamRemote.Read(byteBuffer, 0, byteBuffer.Length)) > 0)
{
if (isCanceled == true) return;
if (manualResetEvent.WaitOne(0, false)) return;
// write the bytes to the file system at the file path specified
streamLocal.Write(byteBuffer, 0, iByteSize);
iRunningByteTotal += iByteSize;
// calculate the progress out of a base "100"
double dIndex = (double)(iRunningByteTotal);
double dTotal = (double)byteBuffer.Length;
double dProgressPercentage = (dIndex / dTotal);
int iProgressPercentage = (int)(dProgressPercentage * 100);
UpdateProgress((int)iProgressPercentage, count);
}
// clean up the file stream
streamLocal.Close();
}
// close the connection to the remote server
streamRemote.Close();
}
}
例外:
System.OverflowException was caught
HResult=-2146233066
Message=Arithmetic operation resulted in an overflow.
Source=Downloader
StackTrace:
at MetroFramework.Demo.frmMain.FileDownloader(Object state) in frmMain.cs:line 595--->byte[] byteBuffer = new byte[iSize];
InnerException:
乍一看,您似乎已經正確地完成了所有操作:
一切...保存一件事:
byte[] byteBuffer = new byte[iSize];
這會將緩沖區分配為要下載的文件的大小。 換句話說,如果文件的大小為1GiB,則分配1GiB的緩沖區,然后嘗試在一個調用中填充整個緩沖區。 這種填充可能返回較少的字節,但是您仍然分配了整個緩沖區。 請注意,.NET中單個數組的最大長度是一個32位數字,這意味着即使您將程序重新編譯為64位並且實際上有足夠的可用內存,對於大於2GiB的文件,它仍然會失敗。
這樣做:
byte[] byteBuffer = new byte[65536];
使用64KiB緩沖區或其他一些合理的緩沖區大小。
除了@Lasse的答案解決的緩沖區問題之外,實際的問題還在於您正在重新發明輪子。
使用WebClient.DownloadFile()
並訂閱DownloadProgressChanged
事件:
using (System.Net.WebClient client = new System.Net.WebClient())
{
client.DownloadProgressChanged += WebClient_DownloadProgressChanged;
client.DownloadFile(sourceUrl, targetFile);
client.DownloadProgressChanged -= WebClient_DownloadProgressChanged;
}
private void WebClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
// e.BytesReceived,
// e.TotalBytesToReceive,
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.