首页 | IT新闻 | 硬件 | 操作系统 | 开发 | 网络编程 | 数据库 | 热门框架 | 网络安全 | 组网 | 建站指南 | 网页制作 | 特效 | 实用技巧 | 服务器 | 办公 | QQ | 探索 | 社区

  • 技术部落
  • 部落首页 > 程序开发 > C/C#/C++ > 正文
  • 用Visual C#实现文件下载功能
      2007-3-20  来源:网络资源  编辑:Jsbulo  热度:

      实现原理:  

      程序实现的原理比较简单,主要用到了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等文件,所以要做出一个比较好的文件下载器还需读者进一步改进之。