前言
軟件開發(fā)中,文件下載功能是許多應(yīng)用程序的常見需求。對(duì)于用戶而言,不僅希望下載過程穩(wěn)定高效,還希望能夠?qū)崟r(shí)掌握下載進(jìn)度,從而提升用戶體驗(yàn)。而使用 C# .NET 開發(fā)的 WinForm 應(yīng)用程序,我們可以通過簡(jiǎn)單的代碼實(shí)現(xiàn)文件下載,并結(jié)合進(jìn)度條(ProgressBar
)和標(biāo)簽(Label
)來動(dòng)態(tài)顯示下載狀態(tài)。
本文將以一段實(shí)際實(shí)現(xiàn)的代碼為基礎(chǔ),詳細(xì)講解如何在 WinForm 中實(shí)現(xiàn)文件下載及進(jìn)度條展示功能。
正文
整體邏輯
該代碼段的核心函數(shù)是 DownloadFile()
方法,它實(shí)現(xiàn)了從指定 URL 下載文件到本地路徑的功能,并通過進(jìn)度條和標(biāo)簽控件實(shí)時(shí)更新下載進(jìn)度。
主要流程如下:
1、創(chuàng)建 HTTP 請(qǐng)求獲取遠(yuǎn)程文件;
2、獲取文件總大小以設(shè)置進(jìn)度條最大值;
3、創(chuàng)建本地文件流用于寫入數(shù)據(jù);
4、使用循環(huán)讀取網(wǎng)絡(luò)流中的數(shù)據(jù)塊,并寫入本地文件;
5、實(shí)時(shí)計(jì)算并更新下載百分比與進(jìn)度條;
6、異常處理以確保程序穩(wěn)定性。
代碼結(jié)構(gòu)
1、界面部分
界面由一個(gè)按鈕 btnDown_Click
觸發(fā)下載事件。
當(dāng)點(diǎn)擊按鈕后,會(huì)調(diào)用 DownloadFile()
方法,傳入下載地址、保存路徑、進(jìn)度條控件和標(biāo)簽控件作為參數(shù)。
private void btnDown_Click(object sender, EventArgs e)
{
DownloadFile("http://localhost:1928/WebServer/downloader/123.rar", @"C:\123.rar", progressBar1, label1);
}
注意:上傳路徑為 "C:\123.rar"
,注意路徑是否正確以及是否有寫權(quán)限。
2、下載方法
public void DownloadFile(string URL, string filename, System.Windows.Forms.ProgressBar prog, System.Windows.Forms.Label label1)
{
float percent = 0;
try
{
// 創(chuàng)建HTTP請(qǐng)求對(duì)象
System.Net.HttpWebRequest Myrq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(URL);
System.Net.HttpWebResponse myrp = (System.Net.HttpWebResponse)Myrq.GetResponse();
// 獲取文件總大小
long totalBytes = myrp.ContentLength;
// 設(shè)置進(jìn)度條最大值
if (prog != null)
{
prog.Maximum = (int)totalBytes;
}
// 獲取響應(yīng)流和創(chuàng)建文件流
System.IO.Stream st = myrp.GetResponseStream();
System.IO.Stream so = new System.IO.FileStream(filename, System.IO.FileMode.Create);
long totalDownloadedByte = 0;
byte[] by = newbyte[1024];
int osize = st.Read(by, 0, (int)by.Length);
// 循環(huán)讀取并寫入文件
while (osize > 0)
{
totalDownloadedByte += osize;
so.Write(by, 0, osize);
// 更新進(jìn)度條和標(biāo)簽
if (prog != null)
{
prog.Value = (int)totalDownloadedByte;
}
percent = (float)totalDownloadedByte / (float)totalBytes * 100;
label1.Text = "當(dāng)前補(bǔ)丁下載進(jìn)度:" + percent.ToString("#0.00") + "%";
// 刷新UI
System.Windows.Forms.Application.DoEvents();
// 繼續(xù)讀取下一塊數(shù)據(jù)
osize = st.Read(by, 0, (int)by.Length);
}
// 關(guān)閉流
so.Close();
st.Close();
}
catch (Exception ex)
{
MessageBox.Show("下載過程中發(fā)生錯(cuò)誤:" + ex.Message);
}
}
關(guān)鍵技術(shù)
1、多線程問題與 UI 阻塞
由于是直接在主線程中進(jìn)行網(wǎng)絡(luò)下載操作,若不及時(shí)刷新界面,會(huì)導(dǎo)致 UI 卡頓甚至“無響應(yīng)”。因此,代碼中使用了:
System.Windows.Forms.Application.DoEvents();
此方法允許在下載循環(huán)過程中接收和處理 Windows 消息,從而保持界面響應(yīng)。
?? 注意:雖然 DoEvents()
可以暫時(shí)解決問題,但在大型項(xiàng)目或復(fù)雜場(chǎng)景中更推薦使用后臺(tái)線程(如 BackgroundWorker
或 async/await
異步編程模型)來避免阻塞主線程。
2、下載速度與緩沖區(qū)大小
本例中使用的緩沖區(qū)大小為 1KB(1024 字節(jié)),這個(gè)數(shù)值可以根據(jù)實(shí)際情況調(diào)整。
較大的緩沖區(qū)可以提高吞吐量,但也會(huì)增加內(nèi)存占用。
例如改為 8KB:
byte[] by = new byte[8192]; // 更改緩沖區(qū)大小
3、進(jìn)度計(jì)算與格式化顯示
通過比較已下載字節(jié)數(shù)與總字節(jié)數(shù),計(jì)算出百分比:
percent = (float)totalDownloadedByte / (float)totalBytes * 100;
label1.Text = "當(dāng)前補(bǔ)丁下載進(jìn)度:" + percent.ToString("#0.00") + "%";
其中使用了格式字符串 #0.00
來保留兩位小數(shù),使顯示更美觀。
總結(jié)
本文通過完整的WinForm代碼實(shí)現(xiàn)文件下載,深入講解了如何實(shí)現(xiàn)下載功能并配合控件實(shí)時(shí)顯示進(jìn)度。整個(gè)過程簡(jiǎn)潔有效,適用于小型工具類應(yīng)用。
作者:小小工具箱
出處:blog.csdn.net/m0_62355555/article/details/126777817
該文章在 2025/5/10 10:30:44 編輯過