C# 使用HttpWebRequest C下载文件部件#

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

我正在尝试使用HttpWebRequest下载一个100GB的文件。下载内容将根据预设的零件尺寸分成多个零件。下面是我用来下载该文件的代码:

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卡的数量