文件的上傳下載是我們在實際項目開發過程中經常需要用到的技術,這里給出幾種常見的方法
文件的上傳下載是我們在實際項目開發過程中經常需要用到的技術,這里給出幾種常見的方法,本文主要內容包括:
1、如何解決文件上傳大小的限制
2、以文件形式保存到服務器
3、轉換成二進制字節流保存到數據庫以及下載方法
4、上傳internet上的資源
第一部分:
首先我們來說一下如何解決asp.net中的文件上傳大小限制的問題,我們知道在默認情況下asp.net的文件上傳大小限制為2m,一般情況下,我們可以采用更改web.config文件來自定義最大文件大小,如下:
<httpruntime executiontimeout="300" maxrequestlength="40960" usefullyqualifiedredirecturl="false"/>這樣上傳文件的最大值就變成了4m,但這樣并不能讓我們無限的擴大maxrequestlength的值,因為asp.net會將全部文件載入內存后,再加以處理。解決的方法是利用隱含的httpworkerrequest,用它的getpreloadedentitybody和readentitybody方法從iis為asp.net建立的pipe里分塊讀取數據。實現方法如下:
iserviceproviderprovider=(iserviceprovider)httpcontext.current;
httpworkerrequestwr=(httpworkerrequest)provider.getservice(typeof(httpworkerrequest));
byte[]bs=wr.getpreloadedentitybody();
.
if(!wr.isentireentitybodyispreloaded())
{
 intn=1024;
 byte[]bs2=newbyte[n];
 while(wr.readentitybody(bs2,n)>0)
 {
  ..
 }
} 
這樣就可以解決了大文件的上傳問題了。
第二部分:
下面我們來介紹如何以文件形式將客戶端的一個文件上傳到服務器并返回上傳文件的一些基本信息。
首先我們定義一個類,用來存儲上傳的文件的信息(返回時需要)。
public class fileupload
{
 public fileupload()
 {}
 /**//// <summary>
 /// 上傳文件名稱
 /// </summary>
 public string filename
 {
  get
  {
   return filename;
  }
  set
  {
   filename = value;
  }
 }
 private string filename;
 /**//// <summary>
 /// 上傳文件路徑
 /// </summary>
 public string filepath
 {
  get
  {
   return filepath;
  }
  set
  {
   filepath = value;
  }
 }
 private string filepath;
 /**//// <summary>
 /// 文件擴展名
 /// </summary>
 public string fileextension
 {
  get
  {
   return fileextension;
  }
  set
  {
   fileextension = value;
  }
 }
 private string fileextension;
} 
另外我們還可以在配置文件中限制上傳文件的格式(app.config):
<?xml version="1.0" encoding="gb2312" ?>
<application> 
<fileupload>
<format>.jpg|.gif|.png|.bmp</format>
</fileupload>
</application>
這樣我們就可以開始寫我們的上傳文件的方法了,如下:
public fileupload uploadfile(htmlinputfile inputfile,string filepath,string myfilename,bool israndom)
{
 fileupload fp = new fileupload();
 string filename,fileextension;
 string savename;
 //
 //建立上傳對象
 //
 httppostedfile postedfile = inputfile.postedfile;
 filename = system.io.path.getfilename(postedfile.filename);
 fileextension = system.io.path.getextension(filename);
 //
 //根據類型確定文件格式
 //
 appconfig app = new appconfig();
 string format = app.getpath("fileupload/format");
 //
 //如果格式都不符合則返回
 //
 if(format.indexof(fileextension)==-1)
 {
  throw new applicationexception("上傳數據格式不合法");
 }
 //
 //根據日期和隨機數生成隨機的文件名
 //
 if(myfilename != string.empty)
 {
  filename = myfilename; 
 }
 if(israndom)
 {
  random objrand = new random();
  system.datetime date = datetime.now;
  //生成隨機文件名
  savename = date.year.tostring() + date.month.tostring() + date.day.tostring() + date.hour.tostring() + date.minute.tostring() + date.second.tostring() + convert.tostring(objrand.next(99)*97 + 100);
  filename = savename + fileextension;
 }
string phypath = httpcontext.current.request.mappath(filepath);
 //判斷路徑是否存在,若不存在則創建路徑
 directoryinfo updir = new directoryinfo(phypath);
 if(!updir.exists)
 {
  updir.create();
 }
 //
 //保存文件
 //
 try
 {
  postedfile.saveas(phypath + filename);
  fp.filepath = filepath + filename;
  fp.fileextension = fileextension;
  fp.filename = filename;
 }
 catch
 {
  throw new applicationexception("上傳失敗!");
 }
 //返回上傳文件的信息
 return fp;
} 
然后我們在上傳文件的時候就可以調用這個方法了,將返回的文件信息保存到數據庫中,至于下載,就直接打開那個路徑就ok了。
第三部分:
這里我們主要說一下如何以二進制的形式上傳文件以及下載。首先說上傳,方法如下:
public byte[] uploadfile(htmlinputfile f_ifile)
{
 //獲取由客戶端指定的上傳文件的訪問
 httppostedfile upfile=f_ifile.postedfile;
 //得到上傳文件的長度
 int upfilelength=upfile.contentlength; 
 //得到上傳文件的客戶端mime類型
 string contenttype = upfile.contenttype;
 byte[] filearray=new byte[upfilelength];
stream filestream=upfile.inputstream;
 filestream.read(filearray,0,upfilelength);
 return filearray;
} 
這個方法返回的就是上傳的文件的二進制字節流,這樣我們就可以將它保存到數據庫了。下面說一下這種形式的下載,也許你會想到這種方式的下載就是新建一個aspx頁面,然后在它的page_load()事件里取出二進制字節流,然后再讀出來就可以了,其實這種方法是不可取的,在實際的運用中也許會出現無法打開某站點的錯誤,我一般采用下面的方法:
首先,在web.config中加入:
<add verb="*" path="openfile.aspx" type="ruixinoa.web.baseclass.openfile, ruixinoa.web"/>
這表示我打開openfile.aspx這個頁面時,系統就會自動轉到執行ruixinoa.web.baseclass.openfile 這個類里的方法,具體實現如下:
using system;
using system.data;
using system.web;
using system.io;
using ruixin.workflowdb;
using rxsuite.base;
using rxsuite.component;
using ruixinoa.businessfacade;
namespace ruixinoa.web.baseclass
{
 /**//// <summary>
 /// netufile 的摘要說明。
 /// </summary>
 public class openfile : ihttphandler
 {
  public void processrequest(httpcontext context) 
  {
   //從數據庫中取出要下載的文件信息
   ruixinoa.businessfacade.rx_oa_filemanager os = new rx_oa_filemanager();
   entitydata data = os.getfiledetail(id);
   if(data != null && data.tables["rx_oa_file"].rows.count > 0)
   {
    datarow dr = (datarow)data.tables["rx_oa_file"].rows[0];
    context.response.buffer = true;
    context.response.clear();
    context.response.contenttype = dr["ccontenttype"].tostring(); 
    context.response.addheader("content-disposition","attachment;filename=" + httputility.urlencode(dr["ctitle"].tostring()));
    context.response.binarywrite((byte[])dr["ccontent"]);
    context.response.flush();
    context.response.end();
   }
  }
  public bool isreusable 
  {  
   get { return true;} 
  }
 }
} 
執行上面的方法后,系統會提示用戶選擇直接打開還是下載。這一部分我們就說到這里。
第四部分:
這一部分主要說如何上傳一個internet上的資源到服務器。
首先需要引用 system.net 這個命名空間,然后操作如下:
httpwebrequest hwq = (httpwebrequest)webrequest.create("http://localhost/pwtest/webform1.aspx");
httpwebresponse hwr = (httpwebresponse)hwq.getresponse();
byte[] bytes = new byte[hwr.contentlength];
stream stream = hwr.getresponsestream();
stream.read(bytes,0,convert.toint32(hwr.contentlength));
//httpcontext.current.response.binarywrite(bytes); 
httpwebrequest 可以從internet上讀取文件,因此可以很好的解決這個問題。
第五部分:總結
今天簡單的介紹了幾種文件上傳與下載的方法,都是在實際的項目開發中經常需要用到的,可能還有不完善的地方,希望大家可以互相交流一下項目開發中的經驗
 
新聞熱點
疑難解答
圖片精選