程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#基礎知識 >> 用Visual C#完成文件下載

用Visual C#完成文件下載

編輯:C#基礎知識

   一.概述:   
    本文通過一個實例向大家介紹用Visual C#進行Internet通訊編程的一些基本知識。我們知道.Net類包含了請求/響應層、應用協議層、傳輸層等層次。在本程序中,我們運用了位於請求/響應層的WebRequest類以及WebClient類等來實現高抽象程度的Internet通訊服務。本程序的功能是完成網絡文件的下載。  
    二.實現原理:   
    程序實現的原理比較簡單,主要用到了WebClient類和FileStream類。其中WebClient類處於System.Net名字空間中,該類的主要功能是提供向URI標識的資源發送數據和從URI標識的資源接收數據的公共方法。我們利用其中的DownloadFile()方法將網絡文件下載到本地。然後用FileStream類的實例對象以數據流的方式將文件數據寫入本地文件。這樣就完成了網絡文件的下載。   
    三.實現步驟:   
    首先,打開Visual Studio.Net,新建一個Visual C# Windows應用程序的工程,不妨命名為"MyGetCar"。
  接著,布置主界面。我們先往主窗體上添加如下控件:兩個標簽控件、兩個文本框控件、一個按鈕控件以及一個狀態欄控件。
    完成主窗體的設計,我們接著完成代碼的編寫。   
    在理解了基本原理的基礎上去完成代碼的編寫是相當容易。程序中我們主要用到的是WebClient類,不過在我們調用WebClient類的實例對象前,我們需要用WebRequest類的對象發出對統一資源標識符(URI)的請求。  
  try
  {
  WebRequest myre=WebRequest.Create(URLAddress);
  }
  catch(WebException exp)
  {
  MessageBox.Show(exp.Message,"Error");
  }   
    這是一個try-catch語句,try塊完成向URI的請求,catch塊則捕捉可能的異常並顯示異常信息。其中的URLAddress為被請求的網絡主機名。   
    在請求成功後,我們就可以運用WebClient類的實例對象中的DownloadFile()方法實現文件的下載了。其函數原型如下:  
     public void DownloadFile( string address, string fileName);   
    其中,參數address為從中下載數據的 URI,fileName為要接收數據的本地文件的名稱。
  之後我們用OpenRead()方法來打開一個可讀的流,該流完成從具有指定URI的資源下載數據的功能。其函數原型如下:
    public Stream OpenRead(string address);    
    其中,參數address同上。   
    最後就是新建一個StreamReader對象從中讀取文件的數據,並運用一個while循環體不斷讀取數據,只到讀完所有的數據。
    還有在使用以上方法時,你將可能需要處理以下幾種異常:   
     WebException:下載數據時發生錯誤。   
     UriFormatException:通過組合 BaseAddress、address 和 QueryString 所構成的 URI 無效。   
    這部分的代碼如下:(client為WebClient對象,在本類的開頭處聲明即可)   
  statusBar.Text = "開始下載文件...";
  client.DownloadFile(URLAddress,fileName);
  Stream str = client.OpenRead(URLAddress);
  StreamReader reader = new StreamReader(str);
  byte[] mbyte = new byte[100000];
  int allmybyte = (int)mbyte.Length;
  int startmbyte = 0;
  statusBar.Text = "正在接收數據...";
  while(allmybyte>0)
  {
  int m = str.Read(mbyte,startmbyte,allmybyte);
  if(m==0)
  break;   
  startmbyte+=m;
  allmybyte-=m;
  }
  
    完成了文件數據的讀取工作後,我們運用FileStream類的實例對象將這些數據寫入本地文件中:  
  FileStream fstr = new FileStream(Path,FileMode.OpenOrCreate,FileAccess.Write);
  fstr.Write(mbyte,0,startmbyte);
    這樣,程序主體部分的代碼已經完成了,不過要完成全部程序還需要一些工作。由於在程序接收網絡文件數據的時候運用到了while循環體,這樣會很占程序資源,表現的形式就是主窗體不能自由移動。為了解決這個問題,我們在程序中用到了多線程機制。我們在響應按鈕的事件中新建一個線程,該線程就是用來實現網絡文件下載功能的。如此,文件下載的線程和程序主線程並存,共享進程資源,使得程序順暢運行。這樣,我們在按鈕控件的消息響應函數裡添加如下代碼:   
  Thread th = new Thread(new ThreadStart(StartDownload));
  th.Start();   
    該線程的實現函數就是StartDownload(),而上面介紹的那些代碼就是這個函數的主體部分。  
    最後,因為程序中運用到了WebRequest、WebClient、FileStream、Thread等類,所以最重要的就是在程序的開始處添加如下名字空間:
  using System.Net;
  using System.IO;
  using System.Threading;


下面就是程序的源代碼:
  
  using System;
  using System.Drawing;
  using System.Collections;
  using System.ComponentModel;
  using System.Windows.Forms;
  using System.Data;
  using System.Net;
  using System.IO;
  using System.Threading;
  
  namespace MyGetCar
  {
  ///
  /// Form1 的摘要說明。
  ///
  public class Form1 : System.Windows.Forms.Form
  {
  private System.Windows.Forms.Label label1;
  private System.Windows.Forms.Label label2;
  private System.Windows.Forms.TextBox srcAddress;
  private System.Windows.Forms.TextBox tarAddress;
  private System.Windows.Forms.StatusBar statusBar;
  private System.Windows.Forms.Button Start;
  
  private WebClient client = new WebClient();
  
  ///
  /// 必需的設計器變量。
  ///
  private System.ComponentModel.Container components = null;
  
  public Form1()
  {
  //
  // Windows 窗體設計器支持所必需的
  //
  InitializeComponent();
  
  //
  // TODO: 在 InitializeComponent 調用後添加任何構造函數代碼
  //
  }
  
  ///
  /// 清理所有正在使用的資源。
  ///
  protected override void Dispose( bool disposing )
  {
  if( disposing )
  {
  if (components != null)
  {
  components.Dispose();
  }
  }
  base.Dispose( disposing );
  }
  
  #region Windows Form Designer generated code
  ///
  /// 設計器支持所需的方法 - 不要使用代碼編輯器修改
  /// 此方法的內容。
  ///
  private void InitializeComponent()
  {
  this.label1 = new System.Windows.Forms.Label();
  this.label2 = new System.Windows.Forms.Label();
  this.srcAddress = new System.Windows.Forms.TextBox();
  this.tarAddress = new System.Windows.Forms.TextBox();
  this.statusBar = new System.Windows.Forms.StatusBar();
  this.Start = new System.Windows.Forms.Button();
  this.SuspendLayout();
  //
  // label1
  //
  this.label1.Location = new System.Drawing.Point(8, 32);
  this.label1.Name = "label1";
  this.label1.Size = new System.Drawing.Size(72, 23);
  this.label1.TabIndex = 0;
  this.label1.Text = "文件地址:";
  this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
  //
  // label2
  //
  this.label2.Location = new System.Drawing.Point(8, 72);
  this.label2.Name = "label2";
  this.label2.Size = new System.Drawing.Size(72, 23);
  this.label2.TabIndex = 1;
  this.label2.Text = "另存到:";
  this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
  //
  // srcAddress
  //
  this.srcAddress.Location = new System.Drawing.Point(80, 32);
  this.srcAddress.Name = "srcAddress";
  this.srcAddress.Size = new System.Drawing.Size(216, 21);
  this.srcAddress.TabIndex = 2;
  this.srcAddress.Text = "";
  //
  // tarAddress
  //
  this.tarAddress.Location = new System.Drawing.Point(80, 72);
  this.tarAddress.Name = "tarAddress";
  this.tarAddress.Size = new System.Drawing.Size(216, 21);
  this.tarAddress.TabIndex = 3;
  this.tarAddress.Text = "";
  //
  // statusBar
  //
  this.statusBar.Location = new System.Drawing.Point(0, 151);
  this.statusBar.Name = "statusBar";
  this.statusBar.Size = new System.Drawing.Size(312, 22);
  this.statusBar.TabIndex = 4;
  //
  // Start
  //
  this.Start.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
  this.Start.Location = new System.Drawing.Point(216, 112);
  this.Start.Name = "Start";
  this.Start.Size = new System.Drawing.Size(75, 24);
  this.Start.TabIndex = 5;
  this.Start.Text = "開始下載";
  this.Start.Click += new System.EventHandler(this.Start_Click);
  //
  // Form1
  //
  this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
  this.ClientSize = new System.Drawing.Size(312, 173);
  this.Controls.AddRange(new System.Windows.Forms.Control[] {
  this.Start,
  this.statusBar,
  this.tarAddress,
  this.srcAddress,
  this.label2,
  this.label1});
  this.MaximizeBox = false;
  this.Name = "Form1";
  this.Text = "文件下載器";
  this.ResumeLayout(false);
  
  }
  #endregion
  
  ///
  /// 應用程序的主入口點。
  ///
  [STAThread]
  static void Main()
  {
  Application.Run(new Form1());
  }
  
  private void StartDownload()
  {
  Start.Enabled = false;
  string URL = srcAddress.Text;
  int n = URL.LastIndexOf("/");
  string URLAddress = URL.Substring(0,n);
  string fileName = URL.Substring(n+1,URL.Length-n-1);
  string Dir = tarAddress.Text;
  string Path = Dir+"\\"+fileName;
  
  try
  {
  WebRequest myre=WebRequest.Create(URLAddress);
  }
  catch(WebException exp)
  {
  MessageBox.Show(exp.Message,"Error");
  }
  
  try
  {
  statusBar.Text = "開始下載文件...";
  client.DownloadFile(URLAddress,fileName);
  Stream str = client.OpenRead(URLAddress);
  StreamReader reader = new StreamReader(str);
  byte[] mbyte = new byte[100000];
  int allmybyte = (int)mbyte.Length;
  int startmbyte = 0;
  statusBar.Text = "正在接收數據...";
  while(allmybyte>0)
  {
  int m = str.Read(mbyte,startmbyte,allmybyte);
  if(m==0)
  break;
  
  startmbyte+=m;
  allmybyte-=m;
  }
  
  FileStream fstr = new FileStream(Path,FileMode.OpenOrCreate,FileAccess.Write);
  fstr.Write(mbyte,0,startmbyte);
  str.Close();
  fstr.Close();
  
  statusBar.Text = "下載完畢!";
  }
  catch(WebException exp)
  {
  MessageBox.Show(exp.Message,"Error");
  statusBar.Text = "";
  }
  
  Start.Enabled = true;
  }
  
  
  private void Start_Click(object sender, System.EventArgs e)
  {
  Thread th = new Thread(new ThreadStart(StartDownload));
  th.Start();
  }
  }
  }      
    四.總結:  
    以上我通過一個實例向大家展示了如何用Visual C#實現網絡文件的下載,我們不難發現用Visual C#進行Internet通訊編程是非常方便的。在上面的程序中,我們僅僅用到了WebClient類的一些方法,而WebClient類不光提供了網絡文件下載的方法,還提供了文件上傳的方法,有興趣的讀者不妨一試――用之實現一個文件上傳器。同時這個程序只是一個非常簡單的例子,程序下載完一個網頁後,它所獲得的僅僅是主頁面的內容,並不能獲得其中的圖片、CSS等文件,所以要做出一個比較好的文件下載器還需讀者進一步改進之。


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved