But how could you live and have no story to tell!
访问统计 original graphics

           一.概述:  
      
       本文通过一个实例向大家介绍用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的资源下载数据的功能。其函数原型如下:  
      
      ublic   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等文件,所以要做出一个比较好的文件下载器还需读者进一步改进之。

转自:http://hi.baidu.com/zhiqingcn/blog/item/da7209179a2c69054b90a725.html

posted on 2009-03-23 14:52  nextsoft  阅读(871)  评论(0编辑  收藏  举报