Csharp 檔案下載程式

之前寫過利用Csharp的WebRequest來下載網頁的內容,這個範例下載的內容是文字內容,如果要下載binary二位元的檔案,就需要修改原本使用的StreamReader變成使用Stream,在之前的範例都有補上內容了,另外還針對deflate及Gzip網頁壓縮功能進行了支援。

這個範例裡使用了Thread來監控下載進度顯示於ProgressBar上。

CsharpProgressBar1




其中一個Thread負責下載檔案,一個Thread監控目前下載的總byte數/檔案大小,還有一個Thread負責invoke delegate委派的事件來調整ProgressBar數量。

CsharpProgressBar2

不過這個範例是利用header裡的Content-Length來取得檔案大小的,所以有時直接下載檔案時,主機並不會把Content-Length設定,所以程式就無法執行了,如果是自己的Web Server建議可以自己寫一隻程式來控制,先讀取檔案大小設定Content-Length後,再response出檔案。

CsharpProgressBar3

WebModule下載部份

        private decimal bytesProcessed = 0;
private decimal bytesTotal = 0;
public decimal getByteTotal()
{
return bytesTotal;
}
public decimal ByteProcess()
{
return bytesProcessed;
}
public decimal DownloadFile(string sUrl, string data, string referer, String localFilename)
{
// Function will return the number of bytes processed
// to the caller. Initialize to 0 here.
bytesProcessed = 0;
bytesTotal = 0;
// Assign values to these objects here so that they can
// be referenced in the finally block
Stream remoteStream = null;
Stream localStream = null;
WebResponse response = null;
// Use a try/catch/finally block as both the WebRequest and Stream
HttpWebRequest URLConn = null;
try
{
// sUrl = sUrl.IndexOf(Prop.getProp()["server"]) > -1 ? sUrl : (Prop.getProp()["server"] + sUrl);
Console.WriteLine(sUrl);
//URL連線
URLConn = (HttpWebRequest)WebRequest.Create(sUrl);
//連線最大等待時間
URLConn.Timeout = 60000;
URLConn.Method = "POST";
//設定Header模擬瀏覽器
URLConn.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.0; zh-TW; rv:1.9.1.2) "
+ "Gecko/20090729 Firefox/3.5.2 GTB5 (.NET CLR 3.5.30729)";
URLConn.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
URLConn.Headers.Set("Accept-Language",
"zh-tw,en-us;q=0.7,en;q=0.3");
URLConn.Headers.Set("Accept-Charse",
"Big5,utf-8;q=0.7,*;q=0.7");
URLConn.Headers["Accept-Encoding"] = "gzip, deflate";
//設定referer
if (referer != null)
{
URLConn.Referer = referer;
}
//純文字傳送,使用application/x-www-form-urlencoded
//如需傳送檔案,則需用multipart/form-data
URLConn.ContentType = "application/x-www-form-urlencoded";
//自動從導
URLConn.AllowAutoRedirect = true;
if (data == null)
data = "";
Console.WriteLine(data);
//把要傳送的資料變成binary
byte[] bytes = Encoding.UTF8.GetBytes(data);
URLConn.ContentLength = bytes.Length;
//設定Cookie,Session
URLConn.CookieContainer = cookie;
//送出post資料
if (data.Length > 0)
{
Stream oStreamOut = URLConn.GetRequestStream();
oStreamOut.Write(bytes, 0, bytes.Length);
//oStreamOut.Close();
}
string sResponseHeader = URLConn.GetResponse().Headers["Content-Length"];
bytesTotal = Convert.ToInt32(sResponseHeader);
response = URLConn.GetResponse();
if (response != null)
{
// Once the WebResponse object has been retrieved,
// get the stream object associated with the response's data
remoteStream = response.GetResponseStream();
// Create the local file
localStream = File.Create(localFilename);
// Allocate a 1k buffer
byte[] buffer = new byte[1024];
int bytesRead;
// Simple do/while loop to read from stream until
// no bytes are returned
Object o = new Object();
do
{
// Read data (up to 1k) from the stream
bytesRead = remoteStream.Read(buffer, 0, buffer.Length);
// Write the data to the local file
localStream.Write(buffer, 0, bytesRead);
//Console.WriteLine(bytesProcessed + "\t" + bytesTotal);
// Increment total bytes processed
//Console.WriteLine(bytesProcessed);
bytesProcessed += bytesRead;
} while (bytesRead > 0);
//bytesProcessed = bytesTotal;
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
// Close the response and streams objects here 
// to make sure they're closed even if an exception
// is thrown at some point
if (response != null) response.Close();
if (remoteStream != null) remoteStream.Close();
if (localStream != null) localStream.Close();
}
// Return total bytes processed to caller.
return bytesProcessed;
}

Manager 檔案下載Manager主程式

using System;
using System.Windows.Forms;
using System.Threading;
namespace DownLoadManagerTest
{
public partial class Manager : Form
{
public Manager()
{
InitializeComponent();
}
private bool dlsuccess = false;
private void go()
{
bool f = true;
while (f)
{
if (web == null)
{
web = new WebModule();
Thread t = new Thread(() => web.DownloadFile(textBox1.Text , "", null,textBox2.Text ));
t.Start();
}
ThreadStart ts = new ThreadStart(myUI);
Thread th = new Thread(ts);
th.Start();
if (web.getByteTotal() != 0 && web.ByteProcess() >= web.getByteTotal())
{
dlsuccess = true;
f = false;
}
Thread.Sleep(1000);
}
Thread cts = new Thread(() => myClose(dlsuccess));
cts.Start();
}
private WebModule web = null;
//delegate委派
private delegate void myUICallBack();
private void myUI( )
{
if (this.InvokeRequired)
{
myUICallBack myUpdate = new myUICallBack(myUI);
this.Invoke(myUpdate);
}
else
{
if (web.getByteTotal() != 0)
{
Console.WriteLine (web.ByteProcess() + "--\t" + web.getByteTotal() + "--\t" + ((web.ByteProcess() / web.getByteTotal())));
progressBar.Value = (Int32)((web.ByteProcess() / web.getByteTotal()) * 100);
}
}
}
private string msg = "下載失敗!";
private delegate void myCloseCallBack(Boolean f);
private void myClose(Boolean f)
{
if (this.InvokeRequired)
{
myCloseCallBack myUpdate = new myCloseCallBack(myClose);
this.Invoke(myUpdate,f);
}
else
{
if(f)
{
MessageBox.Show(this, "程序執行完成!");
}
else
{
MessageBox.Show(this, msg);
}
Close();
Dispose();
}
}
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
Thread th = new Thread(() => go());
th.Start();
}
}
}

Source原始碼下載

本機下載

One thought to “Csharp 檔案下載程式”

發表迴響