文件的上傳下載是我們在實際項目開發(fā)過程中經常需要用到的技術,這里給出幾種常見的方法,本文主要內容包括:
1、如何解決文件上傳大小的限制
2、以文件形式保存到服務器
3、轉換成二進制字節(jié)流保存到數據庫以及下載方法
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);
            //判斷路徑是否存在,若不存在則創(chuàng)建路徑
            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;
}
這個方法返回的就是上傳的文件的二進制字節(jié)流,這樣我們就可以將它保存到數據庫了。下面說一下這種形式的下載,也許你會想到這種方式的下載就是新建一個aspx頁面,然后在它的page_load()事件里取出二進制字節(jié)流,然后再讀出來就可以了,其實這種方法是不可取的,在實際的運用中也許會出現無法打開某站點的錯誤,我一般采用下面的方法:
首先,在web.config中加入:
<add verb="*" path="openfile.aspx" type="ruixinoa.web.baseclass.openfile, ruixinoa.web"/>
這表示我打開openfile.aspx這個頁面時,系統(tǒng)就會自動轉到執(zhí)行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;} 
        }
    }
}
執(zhí)行上面的方法后,系統(tǒng)會提示用戶選擇直接打開還是下載。這一部分我們就說到這里。
第四部分:
    這一部分主要說如何上傳一個internet上的資源到服務器。前面我們有一篇文章詳細介紹了使用方法,這里我不再多說。
請參考:將動態(tài)頁面轉化成二進制字節(jié)流 
第五部分:總結
    今天簡單的介紹了幾種文件上傳與下載的方法,都是在實際的項目開發(fā)中經常需要用到的,可能還有不完善的地方,希望大家可以互相交流一下項目開發(fā)中的經驗。寫的不好的地方,請指正,謝謝!
email:[email protected]3.com 
posted on 2006-05-24 22:48 shy520 閱讀(3256) 評論(17)  編輯 收藏 引用 收藏至365key 所屬分類: asp.net1.1 
 
評論: 
# re: asp.net中文件上傳下載方法集合 2006-05-25 09:54 | ivan
不錯。特別是第三部分的下載,特別感謝。  回復
  
# re: asp.net中文件上傳下載方法集合 2006-05-25 10:19 | 靜思已過
學習 
  回復
  
# re: asp.net中文件上傳下載方法集合 2006-05-25 10:26 | iamsunrise
這也叫集合,拉到。  回復
  
# re: asp.net中文件上傳下載方法集合 2006-05-25 10:31 | onekey
謝謝了,寫得很實用  回復
  
# re: asp.net中文件上傳下載方法集合 2006-05-25 10:35 | shy520
@ivan,靜思已過,onekey 
不客氣,還有不完善的地方,我陸續(xù)加上 
  回復
  
# re: asp.net中常用的文件上傳下載方法 2006-05-25 10:39 | shy520
@iamsunrise 
多謝提醒,名稱已改,:)  回復
  
# re: asp.net中常用的文件上傳下載方法 2006-05-25 11:06 | tianjj
能不能詳細說一下如何作用:隱含的httpworkerrequest 
和你上傳的時候,怎么關聯(lián)。 
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) 
{ 
.. 
} 
}  回復
  
# re: asp.net中常用的文件上傳下載方法 2006-05-25 11:14 | shy520
@tianjj 
我一般就通過修改配置文件來改上傳文件的大小,基本上也夠用了. 
這種方法具體我還沒試過,回去研究下,再發(fā)上來.:-)  回復
  
# re: asp.net中常用的文件上傳下載方法 2006-05-25 11:18 | fuyude.net
@tianjj 
這個其實就是一個httphandler模塊.  回復
  
# re: asp.net中常用的文件上傳下載方法 2006-05-25 11:20 | shy520
@fuyude.net 
呵呵,多謝提醒了  回復
  
# re: asp.net中常用的文件上傳下載方法 2006-06-06 00:32 | htusoft
entitydata data = os.getfiledetail(id); 
請問id 用什么方法傳達進去的? 
  回復
  
# re: asp.net中常用的文件上傳下載方法 2006-06-06 08:36 | shy520
@htusoft 
這句只是說明一下得到要下載文件的明細,可以替換成自己的方法,例子中用的是websharp框架  回復
  
# re: asp.net中常用的文件上傳下載方法 2006-07-08 18:01 | htusoft
我就是想知道,如果我?guī)б粋€參數openfile.aspx?id=0001, 
怎樣把這個參數傳入openfile 類,用querystring可以嗎? 
應該不可以吧,因為openfile 類不是從openfile.aspx的page基類繼承而來。  回復
  
# re: asp.net中常用的文件上傳下載方法 2006-07-08 19:52 | shy521
@htusoft 
可以用querystring傳值  回復
  
# re: asp.net中常用的文件上傳下載方法 2006-07-08 19:54 | shy521
不過我的openfile類是繼承ihttphandler的,這樣就可以了  回復
  
# re: asp.net中常用的文件上傳下載方法 2006-07-08 22:00 | htusoft
這樣也會顯示一個openfile.aspx頁面。可不可以不讓它顯示  回復
  
# re: asp.net中常用的文件上傳下載方法 2006-07-09 15:34 | shy520
@htusoft 
這個我不清楚,這應該是比較好的一種方法了  回復
新聞熱點
疑難解答
圖片精選