Winform中文件的下載


1、直接下載

using (HttpClient http = new HttpClient())
{
    var httpResponseMessage = await http.GetAsync("http://localhost:813/新建文件夾2.rar", HttpCompletionOption.ResponseHeadersRead);//發送請求
    var contentLength = httpResponseMessage.Content.Headers.ContentLength;//讀取文件大小
using (var stream = await httpResponseMessage.Content.ReadAsStreamAsync())//讀取文件流 { var readLength = 1024000;//1000K 每次讀取大小 byte[] bytes = new byte[readLength]; int writeLength; while ((writeLength = stream.Read(bytes, 0, readLength)) > 0)//分塊讀取文件流 { using (FileStream fs = new FileStream(Application.StartupPath + "/temp.rar", FileMode.Append, FileAccess.Write))//使用追加方式打開一個文件流 { fs.Write(bytes, 0, writeLength);//追加寫入文件 contentLength -= writeLength; if (contentLength == 0)//如果寫入完成 給出提示 MessageBox.Show("下載完成"); } } } }

 

2、異步下載

//開啟一個異步線程
await Task.Run(async () =>
{
    //異步操作UI元素
    label1.Invoke((Action)(() =>
    {
        label1.Text = "准備下載...";
    }));

    long downloadSize = 0;//已經下載大小
    long downloadSpeed = 0;//下載速度
    using (HttpClient http = new HttpClient())
    {
        var httpResponseMessage = await http.GetAsync("http://localhost:8088/wms_manual.pdf", HttpCompletionOption.ResponseHeadersRead);//發送請求
        var contentLength = httpResponseMessage.Content.Headers.ContentLength;   //文件大小
                                                                                 //
        using (var stream = await httpResponseMessage.Content.ReadAsStreamAsync())
        {
            var readLength = 1024000;//1000K
            byte[] bytes = new byte[readLength];
            int writeLength;
            var beginSecond = DateTime.Now.Second;//當前時間秒
            while ((writeLength = stream.Read(bytes, 0, readLength)) > 0)
            {
                //使用追加方式打開一個文件流
                using (FileStream fs = new FileStream(Application.StartupPath + "/temp.rar", FileMode.Append, FileAccess.Write))
                {
                    fs.Write(bytes, 0, writeLength);
                }
                downloadSize += writeLength;
                downloadSpeed += writeLength;
                progressBar1.Invoke((Action)(() =>
                {
                    var endSecond = DateTime.Now.Second;
                    if (beginSecond != endSecond)//計算速度
                    {
                        downloadSpeed = downloadSpeed / (endSecond - beginSecond);
                        label1.Text = "下載速度" + downloadSpeed / 1024 + "KB/S";

                        beginSecond = DateTime.Now.Second;
                        downloadSpeed = 0;//清空
                    }
                    progressBar1.Value = Math.Max((int)(downloadSize * 100 / contentLength), 1);
                }));
            }

            label1.Invoke((Action)(() =>
            {
                label1.Text = "下載完成";
            }));
        }
    }
});

 

3、斷點續傳

/// <summary>
/// 是否暫停
/// </summary>
static bool isPause = true;
/// <summary>
/// 下載開始位置(也就是已經下載了的位置)
/// </summary>
static long rangeBegin = 0;//(當然,這個值也可以存為持久化。如文本、數據庫等)

/// <summary>
/// 斷線續傳
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void button3_ClickAsync(object sender, EventArgs e)
{
    isPause = !isPause;
    if (!isPause)//點擊下載
    {
        button3.Text = "暫停";

        await Task.Run(async () =>
        {
            //異步操作UI元素
            label1.Invoke((Action)(() =>
           {
               label1.Text = "准備下載...";
           }));

            long downloadSpeed = 0;//下載速度
            using (HttpClient http = new HttpClient())
            {
                //var url = "http://localhost:813/新建文件夾2.rar";  //a標簽下載鏈接
                var url = "http://localhost:8088/wms_manual.pdf";    //我們自己實現的服務端下載鏈接
                var request = new HttpRequestMessage { RequestUri = new Uri(url) };
                request.Headers.Range = new RangeHeaderValue(rangeBegin, null);//【關鍵點】全局變量記錄已經下載了多少,然后下次從這個位置開始下載。
                var httpResponseMessage = await http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
                var contentLength = httpResponseMessage.Content.Headers.ContentLength;//本次請求的內容大小
                if (httpResponseMessage.Content.Headers.ContentRange != null) //如果為空,則說明服務器不支持斷點續傳
                {
                    contentLength = httpResponseMessage.Content.Headers.ContentRange.Length;//服務器上的文件大小
                }

                using (var stream = await httpResponseMessage.Content.ReadAsStreamAsync())
                {
                    var readLength = 1024000;//1000K
                    byte[] bytes = new byte[readLength];
                    int writeLength;
                    var beginSecond = DateTime.Now.Second;//當前時間秒
                    while ((writeLength = stream.Read(bytes, 0, readLength)) > 0 && !isPause)
                    {
                        //使用追加方式打開一個文件流
                        using (FileStream fs = new FileStream(Application.StartupPath + "/temp.rar", FileMode.Append, FileAccess.Write))
                        {
                            fs.Write(bytes, 0, writeLength);
                        }
                        downloadSpeed += writeLength;
                        rangeBegin += writeLength;
                        progressBar1.Invoke((Action)(() =>
                        {
                            var endSecond = DateTime.Now.Second;
                            if (beginSecond != endSecond)//計算速度
                            {
                                downloadSpeed = downloadSpeed / (endSecond - beginSecond);
                                label1.Text = "下載速度" + downloadSpeed / 1024 + "KB/S";

                                beginSecond = DateTime.Now.Second;
                                downloadSpeed = 0;//清空
                            }
                            progressBar1.Value = Math.Max((int)((rangeBegin) * 100 / contentLength), 1);
                        }));
                    }

                    if (rangeBegin == contentLength)
                    {
                        label1.Invoke((Action)(() =>
                        {
                            label1.Text = "下載完成";
                        }));
                    }
                }
            }
        });
    }
    else//點擊暫停
    {
        button3.Text = "繼續下載";
        label1.Text = "暫停下載";
    }
}

 

 

4、多線程下載文件

/// <summary>
/// 多線程下載文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void button4_ClickAsync(object sender, EventArgs e)
{
    using (HttpClient http = new HttpClient())
    {
        var url = "http://localhost:8088/wms_manual.pdf";
        var httpResponseMessage = await http.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
        var contentLength = httpResponseMessage.Content.Headers.ContentLength.Value;
        var size = contentLength / 10; //這里為了方便,就直接分成10個線程下載。(當然這是不合理的)
        var tasks = new List<Task>();
        for (int i = 0; i < 10; i++)
        {
            var begin = i * size;
            var end = begin + size - 1;
            var task = FileDownload(url, begin, end, i);
            tasks.Add(task);
        }
        for (int i = 0; i < 10; i++)
        {
            await tasks[i];  //當然,這里如有下載異常沒有考慮、文件也沒有校驗。各位自己完善吧。
            progressBar1.Value = (i + 1) * 10;
        }
        FileMerge(Application.StartupPath + @"\File", "temp.rar");
        label1.Text = "下載完成";
    }
}

/// <summary>
/// 文件下載
/// (如果你有興趣,可以沒個線程弄個進度條)
/// </summary>
/// <param name="begin"></param>
/// <param name="end"></param>
/// <param name="index"></param>
/// <returns></returns>
public Task FileDownload(string url, long begin, long end, int index)
{
    var task = Task.Run(async () =>
    {
        using (HttpClient http = new HttpClient())
        {
            var request = new HttpRequestMessage { RequestUri = new Uri(url) };
            request.Headers.Range = new RangeHeaderValue(begin, end);//【關鍵點】全局變量記錄已經下載了多少,然后下次從這個位置開始下載。
            var httpResponseMessage = await http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);

            using (var stream = await httpResponseMessage.Content.ReadAsStreamAsync())
            {
                var readLength = 1024000;//1000K
                byte[] bytes = new byte[readLength];
                int writeLength;
                var beginSecond = DateTime.Now.Second;//當前時間秒
                var filePaht = Application.StartupPath + "/File/";
                if (!Directory.Exists(filePaht))
                    Directory.CreateDirectory(filePaht);

                try
                {
                    while ((writeLength = stream.Read(bytes, 0, readLength)) > 0)
                    {
                        //使用追加方式打開一個文件流
                        using (FileStream fs = new FileStream(filePaht + index, FileMode.Append, FileAccess.Write))
                        {
                            fs.Write(bytes, 0, writeLength);
                        }
                    }
                }
                catch (Exception)
                {
                    //如果出現異常則刪掉這個文件
                    File.Delete(filePaht + index);
                }
            }
        }
    });

    return task;
}

/// <summary>
/// 合並文件
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public bool FileMerge(string path, string fileName)
{
    //這里排序一定要正確,轉成數字后排序(字符串會按1 10 11排序,默認10比2小)
    foreach (var filePath in Directory.GetFiles(path).OrderBy(t => int.Parse(Path.GetFileNameWithoutExtension(t))))
    {
        using (FileStream fs = new FileStream(Directory.GetParent(path).FullName + @"\" + fileName, FileMode.Append, FileAccess.Write))
        {
            byte[] bytes = System.IO.File.ReadAllBytes(filePath);//讀取文件到字節數組
            fs.Write(bytes, 0, bytes.Length);//寫入文件
        }
        System.IO.File.Delete(filePath);
    }
    Directory.Delete(path);
    return true;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM