注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

水滴石穿

破浪是阵风!

 
 
 

日志

 
 

通过Web Services上传和下载文件  

2009-08-21 10:54:35|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

随着Internet技术的发展和跨平台需求的日益增加,Web Services的应用越来越广,我们不但需要通过Web Services传递字符串信息,而且需要传递二进制文件信息。下面,我们就分别介绍如何通过Web Services从服务器下载文件到客户端和从客户端通过Web Services上载文件到

一:通过Web Services显示和下载文件

 我们这里建立的Web Services的名称为GetBinaryFile,提供两个公共权限控制,这在对安全性有比较高的情况下特别有用。这个功能在以前的ASP程序中可以用Stream对象实现。为了方便读者进行测试,这里列出了全部的源代码,并在源代码里进行介绍和注释。

 首先,建立GetBinaryFile.asmx文件:

 我们可以在VS.NET里新建一个C#的aspxWebCS

using System;

 using System.Collections;

 using System.ComponentModel;

 using System.Data;

 using System.Diagnostics;

 using System.Web;

 using System.Web.UI;

 using System.Web.Services;

 using System.IO;

 namespace xml.sz.luohuedu.net.aspxWebCS

 {

  /// <summary>

  /// GetBinaryFile 的摘要说明。

  /// Web Services名称:GetBinaryFile

  /// 功能:返回服务器上的一个文件对象的二进制字节数组。

  /// </summary>

 [WebService(Namespace="http://xml.sz.luohuedu.net/",

  Description="在Web Services里利用.NET框架进行传递二进制文件。")]

  public class GetBinaryFile : System.Web.Services.WebService

  {

   #region Component Designer generated code

   //Web 服务设计器所必需的

   private IContainer components = null;

   /// <summary>

   /// 清理所有正在使用的资源。

   /// </summary>

   protected override void Dispose( bool disposing )

   {

    if(disposing && components != null)

    {

     components.Dispose();

    }

    base.Dispose(disposing);

   }

   #endregion

    public class Images: System.Web.Services.WebService

   {

    /// <summary>

    /// Web 服务提供的方法,返回给定文件的字节数组。

    /// </summary>

    [WebMethod(Description="Web 服务提供的方法,返回给定文件的字节数组")]

    public byte[] GetImage(string requestFileName)

    {

     ///得到服务器端的一个图片

     ///如果你自己测试,注意修改下面的实际物理路径

     if(requestFileName == null || requestFileName == "")

      return getBinaryFile("D:\\Picture.JPG");

     else

      return getBinaryFile("D:\\" + requestFileName);

    }

    /// <summary>

    /// getBinaryFile:返回所给文件路径的字节数组。

    /// </summary>

    /// <param name="filename"></param>

    /// <returns></returns>

    public byte[] getBinaryFile(string filename)

    {

     if(File.Exists(filename))

     {

      try

      {

       ///打开现有文件以进行读取。

       FileStream s = File.OpenRead(filename);

       return ConvertStreamToByteBuffer(s);

      }

      catch(Exception e)

      {

       return new byte[0];

      }

     }

     else

     {

      return new byte[0];

     }

    }

  /// <summary>

  /// ConvertStreamToByteBuffer:把给定的文件流转换为二进制字节数组。

  /// </summary>

  /// <param name="theStream"></param>

  /// <returns></returns>

    public byte[] ConvertStreamToByteBuffer(System.IO.Stream theStream)

    {

     int b1;

     System.IO.MemoryStream tempStream = new System.IO.MemoryStream();

     while((b1=theStream.ReadByte())!=-1)

     {

      tempStream.WriteByte(((byte)b1));

     }

     return tempStream.ToArray();

    }

     [WebMethod(Description="Web 服务提供的方法,返回给定文件类型。")]

     public string GetImageType()

     {

      ///这里只是测试,您可以根据实际的文件类型进行动态输出

      return "image/jpg";

     }

   }

 }

 } 

一旦我们创建了上面的asmx文件,进行编译后,我们就可以编写客户端的代码来进行调用这个Web Services了。

 我们先“添加Web引用”,输入:http://localhost/aspxWebCS/GetBinaryFile.asmx。下面,我们编写显示文件的中间文件:GetBinaryFileShow.aspx,这里,我们只需要在后代码里编写代码即可,GetBinaryFileShow.aspx.cs文件内容如下:

using System;

 using System.Collections;

 using System.ComponentModel;

 using System.Data;

 using System.Drawing;

 using System.Web;

 using System.Web.SessionState;

 using System.Web.UI;

 using System.Web.UI.WebControls;

 using System.Web.UI.HtmlControls;

 using System.Web.Services;

 namespace aspxWebCS

 {

  /// <summary>

  /// GetBinaryFileShow 的摘要说明。

  /// </summary>

  public class GetBinaryFileShow : System.Web.UI.Page

  {

   private void Page_Load(object sender, System.EventArgs e)

   {

   // 在此处放置用户代码以初始化页面

     ///定义并初始化文件对象;

     xml.sz.luohuedu.net.aspxWebCS.GetBinaryFile.Images oImage;

     oImage = new xml.sz.luohuedu.net.aspxWebCS.GetBinaryFile.Images();

     ///得到二进制文件字节数组;

     byte[] image = oImage.GetImage("");

     ///转换为支持存储区为内存的流

     System.IO.MemoryStream memStream = new System.IO.MemoryStream(image);

     ///定义并实例化Bitmap对象

     Bitmap bm = new Bitmap(memStream);

     ///根据不同的条件进行输出或者下载;

     Response.Clear();

     ///如果请求字符串指定下载,就下载该文件;

     ///否则,就显示在浏览器中。

     if(Request.QueryString["Download"]=="1")

     {

      Response.Buffer = true;

      Response.ContentType = "application/octet-stream";

      ///这里下载输出的文件名字 ok.jpg 为例子,你实际中可以根据情况动态决定。

      Response.AddHeader("Content-Disposition","attachment;filename=ok.jpg");

     }

     else

      Response.ContentType = oImage.GetImageType();

     Response.BinaryWrite(image);

     Response.End();

   }

   #region Web Form Designer generated code

   override protected void OnInit(EventArgs e)

   {

    //

    // CODEGEN:该调用是 ASP.NET Web 窗体设计器所必需的。

    //

    InitializeComponent();

    base.OnInit(e);

   }

   /// <summary>

   /// 设计器支持所需的< >

   /// 此方法的内容。

   /// </summary>

   private void InitializeComponent()

   {

    this.Load += new System.EventHandler(this.Page_Load);

   }

   #endregion

  }

 } 

 最后,我们就编写最终的浏览页面:GetBinaryFile.aspx,这个文件很简单,只需要aspx文件即可,内容如下:

 <%@ Page language="c#" Codebehind="GetBinaryFile.aspx.cs" AutoEventWireup="false"

   Inherits="aspxWebCS.GetBinaryFile" %>

 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >

 <HTML>

   <HEAD>

     <title>通过Web Services显示和下载文件</title>

     <meta name="GENERATOR" Content="Microsoft Visual Studio 7.0">

     <meta name="CODE_LANGUAGE" Content="C#">

     <meta name="vs_defaultClientScript" content="JavaScript">

     <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">

   </HEAD>

   <body MS_POSITIONING="GridLayout">

     <form id="GetBinaryFile" method="post" runat="server">

       <FONT face="宋体">

         <asp:HyperLink id="HyperLink1" NavigateUrl="GetBinaryFileShow.aspx?Download=1"

          runat="server">下载文件</asp:HyperLink>

         <br/>

         <!--下面是直接显示文件-->

         <asp:Image id="Image1" ImageUrl="GetBinaryFileShow.aspx" runat="server"></asp:Image>

       </FONT>

     </form>

   </body>

 </HTML> 

二:通过Web Services上载文件

 向服务器上载文件可能有许多种<>

 using System;

 using System.Collections;

 using System.ComponentModel;

 using System.Data;

 using System.Diagnostics;

 using System.Web;

 using System.Web.Services;

 using System.IO;

 namespace xml.sz.luohuedu.net.aspxWebCS

 {

  /// <summary>

  /// Upload 的摘要说明。

  /// </summary>

  [WebService(Namespace="http://xml.sz.luohuedu.net/",

   Description="在Web Services里利用.NET框架进上载文件。")]

  public class Upload : System.Web.Services.WebService

  {

   public Upload()

   {

    //CODEGEN:该调用是 ASP.NET Web

    InitializeComponent();

   }

   #region Component Designer generated code

   //Web 服务设计器所必需的

   private IContainer components = null;

   /// <summary>

   /// 设计器支持所需的方法 - 不要使用代码编辑器修改

   /// 此方法的内容。

   /// </summary>

   private void InitializeComponent()

   {

   }

   /// <summary>

   /// 清理所有正在使用的资源。

   /// </summary>

   protected override void Dispose( bool disposing )

   {

    if(disposing && components != null)

    {

     components.Dispose();

    }

    base.Dispose(disposing);

   }

   #endregion

   [WebMethod(Description="Web 服务提供的方法,返回是否文件上载成功与否。")]

   public string UploadFile(byte[] fs,string FileName)

   {

    try

    {

     ///定义并实例化一个内存流,以存放提交上来的字节数组。

     MemoryStream m = new MemoryStream(fs);

     ///定义实际文件对象,保存上载的文件。

     FileStream f = new FileStream(Server.MapPath(".") + "\\"

      + FileName, FileMode.Create);

     ///把内内存里的数据写入物理文件

     m.WriteTo(f);

     m.Close();

     f.Close();

     f = null;

     m = null;

     return "文件已经上传成功。";

    }

    catch(Exception ex)

    {

     return ex.Message;

    }

   }

 }

 } 

要上载文件,必须提供一个表单,来供用户进行文件的选择,下面我们就建立这样一个页面Upload.aspx,用来提供文件上载:

<%@ Page language="c#" Codebehind="Upload.aspx.cs" AutoEventWireup="false"

   Inherits="aspxWebCS.Upload" %>

 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

 <HTML>

   <HEAD>

     <title>通过Web Services上载文件</title>

     <meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.0">

     <meta name="CODE_LANGUAGE" content="Visual Basic 7.0">

     <meta name="vs_defaultClientScript" content="JavaScript">

     <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">

   </HEAD>

   <body MS_POSITIONING="GridLayout">

     <form id="Form1" method="post" runat="server"  enctype="multipart/form-data">

       <INPUT id="MyFile" type="file" runat="server">

       <br>

       <br>

       <asp:Button id="Button1" runat="server" Text="上载文件"></asp:Button>

     </form>

   </body>

 </HTML> 

 我们要进行处理的是在后代码里面,下面详细的介绍,Upload.aspx.cs:

 using System;

 using System.Collections;

 using System.ComponentModel;

 using System.Data;

 using System.Drawing;

 using System.Web;

 using System.Web.SessionState;

 using System.Web.UI;

 using System.Web.UI.WebControls;

 using System.Web.UI.HtmlControls;

 using System.Web.Services;

 using System.IO;

 namespace aspxWebCS

 {

  /// <summary>

  /// Upload 的摘要说明。

  /// 利用该<>

  /// </summary>

  public class Upload : System.Web.UI.Page

  {

   protected System.Web.UI.HtmlControls.HtmlInputFile MyFile;

   protected System.Web.UI.WebControls.Button Button1;

   private void Page_Load(object sender, System.EventArgs e)

   {

    // 在此处放置用户代码以初始化页面

   }

   #region Web Form Designer generated code

   override protected void OnInit(EventArgs e)

   {

    //

    // CODEGEN:该调用是 ASP.NET Web 窗体设计器所必需的。

    //

    InitializeComponent();

    base.OnInit(e);

   }

   /// <summary>

   /// 设计器支持所需的方法 - 不要使用代码编辑器修改

   /// 此方法的内容。

   /// </summary>

   private void InitializeComponent()

   {

    this.Button1.Click += new System.EventHandler(this.Button1_Click);

    this.Load += new System.EventHandler(this.Page_Load);

   }

   #endregion

   private void Button1_Click(object sender, System.EventArgs e)

   {

    ///首先得到上载文件信息和文件流

    if(MyFile.PostedFile != null)

    {

     System.Web.HttpFileCollection oFiles;

     oFiles = System.Web.HttpContext.Current.Request.Files;

     if(oFiles.Count < 1)

     {

      Response.Write ("请选择文件。");

      Response.End();

     }

     string FilePath = oFiles[0].FileName;

     if(FilePath == "" || FilePath == null)

     {

      Response.Write ("请选择一个文件。");

      Response.End();

     }

     string FileName = FilePath.Substring(FilePath.LastIndexOf("\\")+1);

     try

     {

      ///处理上载的文件流信息。

      byte[] b = new byte[oFiles[0].ContentLength];

      System.IO.Stream fs;

      xml.sz.luohuedu.net.aspxWebCS.Upload o;

      o = new xml.sz.luohuedu.net.aspxWebCS.Upload();

      fs = (System.IO.Stream)oFiles[0].InputStream;

      fs.Read(b, 0, oFiles[0].ContentLength);

      ///调用Web Services的UploadFile方法进行上载文件。

      Response.Write(o.UploadFile(b, FileName));

      fs.Close();

     }

     catch(Exception ex)

     {

      Response.Write(ex.Message);

     }

    }

    else

    {

  Response.Write("请选择文件");

 }

   }

  }

 } 

后,需要注意的是:在保存文件时,您应该确保指定文件的完整路径(例如,"C:\MyFiles\Picture.jpg"),并确保为 ASP.NET 使用的帐户提供要存储文件的目录的写权限。上载大文件时,可使用 元素的 maxRequestLength 属性来增加文件大小的最大允许值,例如:


 <configuration>

    <system.web>

     <httpRuntime maxRequestLength="1048576" executionTimeout="3600" />

    </system.web>

 </configuration> 

 其中:maxRequestLength:指示 ASP.NET 支持的HTTP方式上载的最大字节数。该限制可用于防止因用户将大量文件传递到该服务器而导致的拒绝服务攻击。指定的大小以 KB 为单位。默认值为 4096 KB (4 MB)。executionTimeout:指示在被 ASP.NET 自动关闭前,允许执行请求的最大秒数。在当文件超出指定的大小时,如果浏览器中会产生 DNS 错误或者出现配置,把配置数加大。

 另外,上载大文件时,还可能会收到以下错误信息:

aspnet_wp.exe (PID: 1520) 被回收,因为内存< RAM MB >

 如果遇到此错误信息,请增加应用程序的 Web.config 文件的

元素中 memoryLimit 属性的值。例如:

 <configuration>

    <system.web>

       <processModel memoryLimit="80"/>

    </system.web>

 </configuration> 

 我在自己的机器上测试,可以上传50M以上的文件。以上代码在Windows XP + .NET 1.0 + VS.NET2002下测试通过。

  评论这张
 
阅读(221)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017