C# 使用HttpWebRequest C下载文件部件#
我正在尝试使用HttpWebRequest下载一个100GB的文件。下载内容将根据预设的零件尺寸分成多个零件。下面是我用来下载该文件的代码:C# 使用HttpWebRequest C下载文件部件#,c#,.net,visual-studio-2010,download,httpwebrequest,C#,.net,Visual Studio 2010,Download,Httpwebrequest,我正在尝试使用HttpWebRequest下载一个100GB的文件。下载内容将根据预设的零件尺寸分成多个零件。下面是我用来下载该文件的代码: private static void AddRangeHeaderHack(WebHeaderCollection headers, long start, long end) { // Original workaround by Eric Cadwell, code taken from
private static void AddRangeHeaderHack(WebHeaderCollection headers, long start, long end)
{
// Original workaround by Eric Cadwell, code taken from
// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=93714
Type type = headers.GetType();
System.Reflection.MethodInfo setAddVerified = type.GetMethod("SetAddVerified",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.FlattenHierarchy
);
string rangeHeaderValue = String.Format("bytes={0}-{1}", start, end);
if (setAddVerified != null)
setAddVerified.Invoke(headers, new object[] { "Range", rangeHeaderValue });
}
private ulong GetRemoteFileSize(string URI)
{
ulong size = 0;
HttpWebRequest req = null;
try
{
req = (HttpWebRequest)WebRequest.Create(URI);
using (var res = (HttpWebResponse)req.GetResponse())
{
size = (ulong)res.ContentLength;
res.Close();
}
}
catch (Exception ex)
{
}
if (req != null)
{
try
{
req.Abort();
req = null;
}
catch (Exception)
{
}
}
return size;
}
private int DownloadFromLink(string sSource, string sDestination)
{
int nRetryCount = 0;
int nMaxRetry = 5;
var lastProgress = DateTime.Now;
ulong offset = 0;
var bRetrying = false;
var bResumable = false;
var fileSize = GetRemoteFileSize(sSource);
if (fileSize > 0)
bResumable = true;
while (true)
{
HttpWebRequest webRequest = null;
try
{
try
{
bRetrying = false;
do
{
try
{
if (bDownloadAbort)
{
return -1;
}
webRequest = (HttpWebRequest)WebRequest.Create(sSource);
webRequest.Timeout = 3600000;
if (offset > 0)
{
AddRangeHeaderHack(webRequest.Headers, (long)offset, (long)fileSize);
}
// Retrieve the response from the server
using (var webResponse = (HttpWebResponse)webRequest.GetResponse())
{
var acceptRanges = String.Compare(webResponse.Headers["Accept-Ranges"], "bytes", true) == 0;
// Open the URL for download
using (var streamResponse = webResponse.GetResponseStream())
{
if (streamResponse != null)
{
// Create a new file stream where we will be saving the data (local drive)
using (var streamLocal = new FileStream(sDestination, offset>0?FileMode.Append:FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
{
// It will store the current number of bytes we retrieved from the server
int bytesSize = 0;
// A buffer for storing and writing the data retrieved from the server
byte[] downBuffer = new byte[/*16384*/ 1024 * 1024];
bool binitialtry = true;
int nRetries = 0;
if (offset > 0)
{
streamLocal.Seek((long)offset, SeekOrigin.Begin);
}
// Loop through the buffer until the buffer is empty
while ((bytesSize = streamResponse.Read(downBuffer, 0, downBuffer.Length)) > 0
|| (File.Exists(sDestination) && (offset < (ulong)fileSize) && nRetries < 5 && bResumable))
{
if (binitialtry && bytesSize == 0)
{
binitialtry = false;
}
if (!binitialtry && bytesSize == 0)
{
nRetries++;
bRetrying = nRetries<5;
break;
}
if (bDownloadAbort)
{
try { streamLocal.Close(); }
catch { }
return;
}
try
{
// Write the data from the buffer to the local hard drive
streamLocal.Write(downBuffer, 0, bytesSize);
offset += (ulong)bytesSize;
}
catch (IOException ex)
{
if (streamResponse != null)
streamResponse.Close();
if (streamLocal != null)
streamLocal.Close();
if (webRequest != null)
webRequest.Abort();
return -1;
}
Interlocked.Add(ref actualDownloaded, bytesSize);
}
// When the above code has ended, close the streams
if (streamResponse != null)
streamResponse.Close();
if (streamLocal != null)
try { streamLocal.Close(); }
catch { }
if (webRequest != null)
webRequest.Abort();
if (webRequest != null)
wcDownload.Dispose();
streamLocal.Close();
}
streamResponse.Close();
}
}
webResponse.Close();
}
if(!bRetrying)
break;
}
catch (IOException ex)
{
if (webRequest != null)
webRequest.Abort();
if (wcDownload != null)
wcDownload.Dispose();
if (nRetryCount <= nMaxRetry)
{
Thread.Sleep(10000);
nRetryCount++;
bRetrying = true;
}
else
{
break;
}
}
catch (UnauthorizedAccessException ex)
{
if (webRequest != null)
webRequest.Abort();
break;
}
catch (WebException ex)
{
if (webRequest != null)
webRequest.Abort();
if (wcDownload != null)
wcDownload.Dispose();
if (nRetryCount <= nMaxRetry)
{
Thread.Sleep(10000);
nRetryCount++;
bRetrying = true;
}
else
{
break;
}
}
finally
{
}
} while (bRetrying);
}
catch (Exception ex)
{
break;
}
}
catch
{
break;
}
if(!bRetrying)
break;
}
}
private static void AddRangeHeaderHack(WebHeaderCollection标题,长起始,长结束)
{
//Eric Cadwell的原始解决方案,代码取自
// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=93714
Type Type=headers.GetType();
System.Reflection.MethodInfo setAddVerified=type.GetMethod(“setAddVerified”,
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Flattery层次结构
);
string rangeHeaderValue=string.Format(“字节={0}-{1}”,开始,结束);
if(setAddVerified!=null)
调用(头,新对象[]{“范围”,rangeHeaderValue});
}
私有ulong GetRemoteFileSize(字符串URI)
{
ulong大小=0;
HttpWebRequest req=null;
尝试
{
req=(HttpWebRequest)WebRequest.Create(URI);
使用(var res=(HttpWebResponse)req.GetResponse())
{
大小=(ulong)res.ContentLength;
res.Close();
}
}
捕获(例外情况除外)
{
}
如果(请求!=null)
{
尝试
{
请求中止();
req=null;
}
捕获(例外)
{
}
}
返回大小;
}
private int DownloadFromLink(字符串源、字符串目标)
{
int nRetryCount=0;
int nMaxRetry=5;
var lastProgress=DateTime.Now;
ulong偏移=0;
var=false;
var bResumable=假;
var fileSize=GetRemoteFileSize(sSource);
如果(文件大小>0)
bResumable=true;
while(true)
{
HttpWebRequest-webRequest=null;
尝试
{
尝试
{
b尝试=错误;
做
{
尝试
{
如果(bDownloadAbort)
{
返回-1;
}
webRequest=(HttpWebRequest)webRequest.Create(sSource);
webRequest.Timeout=3600000;
如果(偏移量>0)
{
AddRangeHeaderHack(webRequest.Headers,(长)偏移量,(长)文件大小);
}
//从服务器检索响应
使用(var webResponse=(HttpWebResponse)webRequest.GetResponse())
{
var acceptRanges=String.Compare(webResponse.Headers[“Accept Ranges”],“bytes”,true)==0;
//打开URL进行下载
使用(var streamResponse=webResponse.GetResponseStream())
{
if(streamResponse!=null)
{
//创建一个新的文件流,我们将在其中保存数据(本地驱动器)
使用(var streamLocal=new FileStream(目标,偏移量>0?FileMode.Append:FileMode.Create,FileAccess.Write,FileShare.ReadWrite))
{
//它将存储我们从服务器检索到的当前字节数
int-bytesSize=0;
//用于存储和写入从服务器检索的数据的缓冲区
byte[]downBuffer=新字节[/*16384*/1024*1024];
bool bininitialtry=真;
int nRetries=0;
如果(偏移量>0)
{
streamLocal.Seek((长)偏移,请参见korigin.Begin);
}
//循环通过缓冲区,直到缓冲区为空
而((bytesSize=streamResponse.Read(downBuffer,0,downBuffer.Length))>0
||(File.Exists(sDestination)和&(offset<(ulong)fileSize)和&nRetries<5和&bResumable))
{
if(binInitialtry&&bytesSize==0)
{
b初始值=假;
}
如果(!binitialtry&&bytesSize==0)
{
nRetries++;
bRetrying=nRetries这可能是服务器设置,根据
使用持久连接的客户端应限制sim卡的数量