zoukankan      html  css  js  c++  java
  • ASP.NET初学笔记:FileUpload控件

    • FileUpLoad控件用于用户向Web应用程序上传文件。文件上传后,可以把文件保存在任意地方,通常把文件保存在文件系统或数据库。向页面添加FileUpLoad控件会自动地为服务器的<form>标签添加enctype="multipart/form-data"属性。

    1.  把文件保存到文件系统

      • 以下代码页面展示了如何使用FileUpLoad控件把图片上传到应用程序。
        [c-sharp] view plaincopy
        1. <%@ Page Language="C#" %>  
        2. <%@ Import Namespace="System.IO" %>  
        3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
        4. <script runat="server">  
        5.     protected void btnAdd_Click(object sender, EventArgs e)  
        6.     {  
        7.         if (upImage.HasFile)  
        8.         {  
        9.             if (CheckFileType(upImage.FileName))  
        10.             {  
        11.                 //用FileUpload.FileName属性得到上传文件名,也可以使用HttpPostedFile.FileName得到。  
        12.                 string filePath = "~/UploadImages/" + upImage.FileName;  
        13.                 //MapPath方法,检索虚拟路径(绝对的或相对的)或应用程序相关的路径映射到的物理路径。  
        14.                 //FileUpload.SavaAs()方法用于把上传文件保存到文件系统中,也可以使用HttpPostedFile.SaveAs()方法。  
        15.                 upImage.SaveAs(MapPath(filePath));  
        16.             }  
        17.         }  
        18.     }  
        19.     bool CheckFileType(string fileName)  
        20.     {  
        21.         //GetExtension()方法返回指定的路径字符串的扩展名。  
        22.         //Path类位于System.IO命名空间中,用于对包含文件或目录路径信息的 String 实例执行操作。  
        23.         string ext = Path.GetExtension(fileName);  
        24.         switch (ext.ToLower())  
        25.         {  
        26.             case ".gif"return true;  
        27.             case ".png"return true;  
        28.             case ".jpg"return true;  
        29.             case ".jpeg"return true;  
        30.             defaultreturn false;  
        31.         }  
        32.     }  
        33.     void Page_PreRender()  
        34.     {  
        35.         string upFolder = MapPath("~/UploadImages/");  
        36.         //在指定的路径中初始化DirectoryInfo类的新实例,DirectoryInfo类公开用于创建、移动和枚举目录和子目录的实例方法。  
        37.         DirectoryInfo dir = new DirectoryInfo(upFolder);  
        38.         //GetFiles,返回当前目录的文件列表。  
        39.         dlstImages.DataSource = dir.GetFiles();  
        40.         dlstImages.DataBind();  
        41.     }  
        42. </script>  
        43.   
        44. <html xmlns="http://www.w3.org/1999/xhtml">  
        45. <head runat="server">  
        46.     <title>无标题页</title>  
        47. </head>  
        48. <body>  
        49.     <form id="form1" runat="server">  
        50.     <div>  
        51.         <asp:Label ID="lblImageFile" runat="server" Text="Image File" AssociatedControlID="upImage"></asp:Label>  
        52.         <asp:FileUpload ID="upImage" runat="server" /><br />  
        53.         <asp:Button ID="btnAdd" runat="server" Text="Add Image" OnClick="btnAdd_Click"/><hr />  
        54.         <asp:DataList ID="dlstImages" RepeatColumns="3" runat="server">  
        55.             <ItemTemplate>  
        56.                 <asp:Image ID="Image1" runat="server" style="200px"  
        57.                     ImageUrl='<%# Eval("Name","~/UploadImages/{0}") %>' />  
        58.                  <br />  
        59.                  <%# Eval("Name") %>  
        60.                  <!--Name,对于文件,获取该文件的名称。对于目录,如果存在层次结构,则获取层次结构中最后一个目录的名称。否则,Name 属性获取该目录的名称。 -->  
        61.             </ItemTemplate>  
        62.         </asp:DataList>  
        63.     </div>  
        64.     </form>  
        65. </body>  
        66. </html>  

        效果:

        • 为在系统中保存文件,asp.net页面关联的Windows帐户必须有足够的权限来保存文件。

        2.  把文件保存到数据库

        • 也可以用FileUpload控件把文件保存到数据库表。在数据库中保存和检索文件会给服务器增加更多压力。但是它也有些优点,首先,可以避免系统权限问题,其次,能更方便地备份信息。下面演示的是如何把Word文档保存到数据库表中。
          [c-sharp] view plaincopy
          1. <%@ Page Language="C#" %>  
          2. <%@ Import Namespace="System.IO" %>  
          3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
          4.   
          5. <script runat="server">  
          6.     protected void btnAdd_Click(object sender, EventArgs e)  
          7.     {  
          8.         if (upFile.HasFile)  
          9.         {  
          10.             //调用SqlDataSource控件的Insert()方法把FileUpLoad控件的FileName和FileBytes属性的值插入本地SQL Express数据库表。  
          11.             //Insert()方法使用InsertCommand SQL字符串和InsertParameters集合中的所有参数执行插入操作。  
          12.             if (CheckFileType(upFile.FileName))  
          13.                 srcFiles.Insert();  
          14.         }  
          15.     }  
          16.     bool CheckFileType(string fileName)  
          17.     {  
          18.         return Path.GetExtension(fileName).ToLower() == ".doc";  
          19.     }  
          20. </script>  
          21.   
          22. <html xmlns="http://www.w3.org/1999/xhtml">  
          23. <head runat="server">  
          24.     <title>无标题页</title>  
          25. </head>  
          26. <body>  
          27.     <form id="form1" runat="server">  
          28.     <div>  
          29.         <asp:Label ID="lblFile" runat="server" AssociatedControlID="upFile" Text="Word Document"></asp:Label>  
          30.         <asp:FileUpload ID="upFile" runat="server" />  
          31.         <asp:Button ID="btnAdd" runat="server" Text="Add Document" OnClick="btnAdd_Click" /><hr />  
          32.           
          33.         <asp:Repeater ID="rptFiles" DataSourceID="srcFiles" runat="server">  
          34.         <ItemTemplate><li>  
          35.         <asp:HyperLink ID="lnkFile" Text='<%Eval("FileName")%>' NavigateUrl='<%Eval("Id","~/FileHandler.ashx?id={0}") %>' runat="server" /></li>  
          36.         </ItemTemplate>  
          37.         </asp:Repeater>  
          38.           
          39.         <asp:SqlDataSource ID="srcFiles" runat="server"  
          40.             ConnectionString="Server=./SQLExpress;Integrated Security=True;  
          41.             AttachDbFilename=|DataDirectory|FilesDB.mdf;User Instance=True"  
          42.             SelectCommand="select Id,FileName from Files"  
          43.             InsertCommand="insert Files(FileName,FileBytes) values (@FileName,@FileBytes)" >  
          44.             <InsertParameters>  
          45.                <asp:ControlParameter Name="FileName" ControlID="upFile" PropertyName="FileName" />  
          46.                <asp:ControlParameter Name="FileBytes" ControlID="upFile" PropertyName="FileBytes" />  
          47.             </InsertParameters>  
          48.         </asp:SqlDataSource>  
          49.         <!--InsertParameters从与SqlDataSource控件相关联的对象获取包含InsertCommand属性所使用的参数的参数集合。-->  
          50.         <!--ControlParameter对象用于将参数设置为ASP.NET网页中的控件的属性值。  
          51.             使用ControlID属性指定控件。使用PropertyName属性指定提供参数值的属性的名称。-->  
          52.         <!--FileBytes以字节数组形式获取上传文件内容。-->  
          53.     </div>  
          54.     </form>  
          55. </body>  
          56. </html>  

          效果:

          页面显示了当前在数据库中Word文档的列表。可以点击其中的文件查看文件内容。点击文档名会链接到FileHandler.ashx页面,这个文件是一个普通的HTTP处理程序文件。当有人用特定的路径请求文件时,HTTP处理程序用于执行代码。下面是FileHandler.ashx文件的代码。
          [c-sharp] view plaincopy
          1. <%@ WebHandler Language="C#" Class="FileHandler" %>  
          2. using System;  
          3. using System.Web;  
          4. using System.Data;  
          5. using System.Data.SqlClient;  
          6. public class FileHandler : IHttpHandler {  
          7.     const string conString = @"Server=./SQLExpress;Integrated Security=True;  
          8.         AttachDbFileName=|DataDirectory|FilesDB.mdf;User Instance=True";   
          9.     public void ProcessRequest (HttpContext context) {  
          10.         context.Response.ContentType = "application/msword";        
          11.         SqlConnection con = new SqlConnection(conString);  
          12.         SqlCommand cmd = new SqlCommand("SELECT FileBytes FROM Files WHERE Id=@Id", con);  
          13.         cmd.Parameters.AddWithValue("@Id", context.Request["Id"]);  
          14.         using (con)  
          15.         {  
          16.             con.Open();  
          17.             byte[] file = (byte[])cmd.ExecuteScalar();  
          18.             context.Response.BinaryWrite(file);  
          19.         }  
          20.     }  
          21.     public bool IsReusable {  
          22.         get {  
          23.             return false;  
          24.         }  
          25.     }  
          26.   
          27. }  
          当请求FileHandler.ashx页面时,执行了ProcessRequest()方法。该方法取得名为Id的查询字符串项,并从数据库表Files中获取匹配的记录。数据库记录包含Word文档内容字节数组。再用Response.BinaryWrite()方法把字节数组发送到浏览器。
          关于HTTP处理程序,现在还没学,上面的FileHandler.ashx页面的代码大部分都不太理解,等以后学到之方面的内容了,再回来解析一下吧。

        3.  上传大文件

        • 上传大文件时,需要做一些额外工作。你可能不希望把服务器端的所有内存都消耗在容纳整个文件上。处理大文件时,需要使用多个可托管(manageable)内存块来处理文件。
          首先,为了处理大文件需要配置应用程序。有两个配置项影响着向服务器提交大文件:httpRuntime maxRequestLength和httpRuntime requestLengthDiskThreshold。maxRequestLength指定提交的表单能被服务器端接收的最大值。默认不能提交大于4MB的表单,否则会得到一个异常。如果要上传超过4MB的文件就需要更改该配置。requestLengthDiskThreshold决定如何把上表单缓存在文件系统。asp.net framework可以把大的文件缓存在文件系统中,当文件大小超过requestLengthDiskThreshold设置后,文件的余下部分被缓存在文件系统(asp.net临时文件夹中)。默认情况下,把超过80KB的提交数据缓存到文件缓存器中,可以修改requestLengthDiskThreshold来设置新的阈值(requestLengthDiskThreshold设置的值必须小于maxRequestLength设置值)。下面代码的Web配置文件设置为可以上传不超过10MB的文件,并把缓存阈值改为100kB。
          <configuration>
            <system.web>
              <httpRuntime maxRequestLength="10240" requestLengthDiskThreshold="100"/>
            </system.web>
          </configuration>
          下面代码演示如何高效地把一个大文件存储到数据库表中。
          [c-sharp] view plaincopy
          1. <%@ Page Language="C#" %>  
          2. <%@ Import Namespace="System.IO" %>  
          3. <%@ Import Namespace="System.Data" %>  
          4. <%@ Import Namespace="System.Data.SqlClient" %>  
          5. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
          6. <script runat="server">  
          7.     const string conString = @"Server=./SQLExpress;Integrated Security=True;AttachDbFilename=|DataDirectory|FilesDB.mdf;User Instance=True";  
          8.     //@在c#中表示后面的字符串强制不转义,在里面的转义字符无效  
          9.     void btnAdd_Click(object sender, EventArgs e)  
          10.     {  
          11.         if (upFile.HasFile)  
          12.         {  
          13.             if (CheckFileType(upFile.FileName))  
          14.             {  
          15.                 AddFile(upFile.FileName, upFile.FileContent);  
          16.                 //FileUpload.FileContent以流(stream)形式获取上传文件内容。  
          17.                 rptFiles.DataBind();  
          18.             }  
          19.         }  
          20.     }  
          21.     bool CheckFileType(string fileName)  
          22.     {  
          23.         return Path.GetExtension(fileName).ToLower() == ".doc";  
          24.     }  
          25.     //Stream类是所有流的抽象基类,提供字节序列的一般视图。  
          26.     void AddFile(string fileName, Stream upload)  
          27.     {  
          28.         SqlConnection con = new SqlConnection(conString);  
          29.         SqlCommand cmd = new SqlCommand("INSERT Files (FileName) Values (@FileName);" + "SELECT @Identity=SCOPE_IDENTITY()", con);  
          30.         //SELECT @Identity=SCOPE_IDENTITY()声明一个参数,在后面传入一个值,可以避免SQL注入,比直接拼SQL语句好  
          31.         //获取添加记录的自增ID。  
          32.         cmd.Parameters.AddWithValue("@FileName", fileName);  
          33.         //SqlCommand.Parameters用于获取SqlParameterCollection。  
          34.         //SqlParameterCollection表示与 SqlCommand 相关联的参数的集合以及各个参数到 DataSet 中列的映射。  
          35.         //AddWithValue将一个值添加到 SqlParameterCollection 的末尾。  
          36.         SqlParameter idParm = cmd.Parameters.Add("@Identity", SqlDbType.Int);  
          37.         idParm.Direction = ParameterDirection.Output;  
          38.   
          39.         using (con)  
          40.         {  
          41.             con.Open();  
          42.             cmd.ExecuteNonQuery();  
          43.             int newFileId = (int)idParm.Value;  
          44.             StoreFile(newFileId, upload, con);  
          45.         }  
          46.         //在using作用域之后自动释放对象(调用Dispose方法),相当于con.close()。  
          47.     }  
          48.       
          49.     void StoreFile(int fileId, Stream upload, SqlConnection connection)  
          50.     {  
          51.         //从流br内读取长度为8040的数据  
          52.         int bufferLen = 8040;  
          53.         BinaryReader br = new BinaryReader(upload);  
          54.         byte[] chunk = br.ReadBytes(bufferLen);  
          55.           
          56.         //修改数据表Files内Id为fileId的数据流为chunk  
          57.         SqlCommand cmd = new SqlCommand("UPDATE Files SET FileBytes=@Buffer WHERE Id=@FileId", connection);  
          58.         cmd.Parameters.AddWithValue("@FileId", fileId);  
          59.         cmd.Parameters.Add("@Buffer", SqlDbType.VarBinary, bufferLen).Value = chunk;  
          60.         cmd.ExecuteNonQuery();  
          61.   
          62.         //###AAA###追加数据表Files内Id为fileId的数据流  
          63.         SqlCommand cmdAppend = new SqlCommand("UPDATE Files SET FileBytes .WRITE(@Buffer, NULL, 0) WHERE Id=@FileId", connection);  
          64.         cmdAppend.Parameters.AddWithValue("@FileId", fileId);  
          65.         cmdAppend.Parameters.Add("@Buffer", SqlDbType.VarBinary, bufferLen);  
          66.         chunk = br.ReadBytes(bufferLen);  
          67.   
          68.         //当br流中有可读数据时,追加至###AAA###  
          69.         while (chunk.Length > 0)  
          70.         {  
          71.             cmdAppend.Parameters["@Buffer"].Value = chunk;  
          72.             cmdAppend.ExecuteNonQuery();  
          73.             chunk = br.ReadBytes(bufferLen);  
          74.         }  
          75.         br.Close(); //关闭流  
          76.     }  
          77. </script>  
          78.   
          79. <html xmlns="http://www.w3.org/1999/xhtml">  
          80. <head runat="server">  
          81.     <title>无标题页</title>  
          82. </head>  
          83. <body>  
          84.     <form id="form1" runat="server">  
          85.     <div>  
          86.     <asp:Label ID="lblFile" runat="server" AssociatedControlID="upFile" Text="Word Document"></asp:Label>  
          87.         <asp:FileUpload ID="upFile" runat="server" />  
          88.         <asp:Button ID="btnAdd" runat="server" Text="Add Document" OnClick="btnAdd_Click" /><hr />  
          89.           
          90.         <asp:Repeater ID="rptFiles" DataSourceID="srcFiles" runat="server">  
          91.         <ItemTemplate>  
          92.         <li>  
          93.         <asp:HyperLink ID="lnkFile" Text='<%#Eval("FileName")%>' NavigateUrl='<%#Eval("Id","~/FileHandlerLarge.ashx?id={0}") %>' runat="server" />  
          94.         </li>  
          95.         </ItemTemplate>  
          96.         </asp:Repeater>  
          97.           
          98.         <asp:SqlDataSource ID="srcFiles" runat="server"  
          99.             ConnectionString="Server=./SQLExpress;Integrated Security=True;  
          100.             AttachDbFilename=|DataDirectory|FilesDB.mdf;User Instance=True"  
          101.             SelectCommand="select Id,FileName from Files" >  
          102.         </asp:SqlDataSource>  
          103.     </div>  
          104.     </form>  
          105. </body>  
          106. </html>  
          在上面代码中,首先调用了AddFile()方法,该方法在包含文件名字段的数据库表Files中新增一行。然后调用StoreFile()方法,该方法把上传文件的实际字节添加到数据库中。上传文件被分成8040字节大小的块。注意在更新数据库字段FileBytes时,SQL UPDATE语句包含.WRITE字句。该代码中的页面不会在内存中装整个上传文件,上传文件以8040字节大小的块从文件系统中取出,产一块一块存入SQL Server中。
          点击文件名将执行FileHandle.aspx HTTP处理程序,该项处理程序从数据库中获取先中的文件并把它发送到浏览器。下面代码包含了这个处理程序。
          [c-sharp] view plaincopy
          1. <%@ WebHandler Language="C#" Class="FileHandlerLarge" %>  
          2. using System;  
          3. using System.Web;  
          4. using System.Data;  
          5. using System.Data.SqlClient;  
          6. public class FileHandlerLarge : IHttpHandler {  
          7.     const string conString = @"Server=./SQLExpress;Integrated Security=True;  
          8.         AttachDbFileName=|DataDirectory|FilesDB.mdf;User Instance=True";  
          9.     public void ProcessRequest (HttpContext context) {  
          10.         context.Response.Buffer = false;  
          11.         context.Response.ContentType = "application/msword";  
          12.         SqlConnection con = new SqlConnection(conString);  
          13.         SqlCommand cmd = new SqlCommand("SELECT FileBytes FROM Files WHERE Id=@Id", con);  
          14.         cmd.Parameters.AddWithValue("@Id", context.Request["Id"]);  
          15.         using (con)  
          16.         {  
          17.             con.Open();  
          18.             SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess);  
          19.             if (reader.Read())  
          20.             {  
          21.                 int bufferSize = 8040;  
          22.                 byte[] chunk = new byte[bufferSize];  
          23.                 long retCount;  
          24.                 long startIndex = 0;  
          25.   
          26.                 retCount = reader.GetBytes(0, startIndex, chunk, 0, bufferSize);  
          27.   
          28.                   
          29.                 while (retCount == bufferSize)  
          30.                 {  
          31.                     context.Response.BinaryWrite(chunk);  
          32.   
          33.                     startIndex += bufferSize;  
          34.                     retCount = reader.GetBytes(0, startIndex, chunk, 0, bufferSize);  
          35.                 }  
          36.   
          37.                 byte[] actualChunk = new Byte[retCount - 1];  
          38.                 Buffer.BlockCopy(chunk, 0, actualChunk, 0, (int)retCount - 1);  
          39.                 context.Response.BinaryWrite(actualChunk);  
          40.                                  
          41.             }  
          42.         }  
          43.     }  
          44.    
          45.     public bool IsReusable {  
          46.         get {  
          47.             return false;  
          48.         }  
          49.     }  
          50.   
          51. }  
          上面代码中的HTTP处理程序使用SqlDataReader从数据库中获取文件。注意,SqlDataReader使用CommandBehavior.SequentialAccess参数获取数据。这个参数使SqlDataReader以流的方式加载数据。数据库字段的内容以8040字节大小的块取入内存中,这些内容块用Response.BinaryWrite()方法写入浏览器。另外注意这个处理程序禁止用了响应缓存,Response.Buffer属性的值被设成False。由于禁用了缓存,处理程序输出就不会在传输到浏览器前缓在服务器端的内存中。
  • 相关阅读:
    【转】JSP三种页面跳转方式
    我要从头做起
    转载:用 Tomcat 和 Eclipse 开发 Web 应用程序
    html的style属性
    Java连接oracle数据库
    tomcat遇到的问题(总结)
    ceshi
    今天要小结一下
    argument.callee.caller.arguments[0]与window.event
    JavaScript事件冒泡简介及应用
  • 原文地址:https://www.cnblogs.com/daban/p/2800035.html
Copyright © 2011-2022 走看看