<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0
    數據加載中……

    Web上傳文件的原理及實現

    本文為原創,如需轉載,請注明作者和出處,謝謝!

    現在有很多Web程序都有上傳功能,實現上傳功能的組件或框架也很多,如基于javaCommons FileUpload、還有Struts1.xStruts2中帶的上傳文件功能(實際上,Struts2在底層也使用了Commons FileUpload)。在asp.net中也有相應的上傳文件的控件。

    雖然現在有很多上傳組件可以利用,但是了解Web上傳文件的原理,對于處理突然出現的問題會有很大的幫助,下面就來講一下通過瀏覽器上傳文件的基本原理。在了解了原理之后,就可以非常容易地自制滿足自身需要的上傳組件了。

    眾所周知,在客戶端代碼中需要使用<input type='file' name='file' />來選擇要上傳的文件,并上傳,代碼如上:

    <html>
        
    <head>
            
    <title>upload</title>
            
    <meta http-equiv="description" content="this is my page">
            
    <meta http-equiv="content-type" content="text/html; charset=GB18030">
        
    </head>

        
    <body>
            
    <form action="servlet/UploadFile" method="post"
                enctype
    ="multipart/form-data">
                
    <input type="file" name="file1" id="file1" />
                
    <input type="file" name="file2" id="file2" />
                
    <input type="submit" value="上傳" />
            
    </form>
        
    </body>
    </html>

    從上面的代碼可以看出,有兩個文件選擇框(file1file2),在上傳文件時,<form>標簽必須加上enctype="multipart/form-data",否則瀏覽器無法將文件內容上傳到服務端。下面我們來做個實驗。在ServletdoPost方法中編寫如下的代碼,如果想使用asp.net或其他的語言或技術,也可以很容易實現相應的功能。

        public void doPost(HttpServletRequest request, HttpServletResponse response)
                
    throws ServletException, IOException
        {
            java.io.InputStream is 
    = request.getInputStream();
            java.io.FileOutputStream fos 
    = new java.io.FileOutputStream("d:\\out.txt");
            
            
    byte[] buffer = new byte[8192];
            
    int count = 0;
            
    while((count = is.read(buffer)) >0)
            {
                fos.write(buffer, 
    0, count);
            }        
            fos.close();
        }

        上面的功能非常簡單,只是通過request獲得一個InputStream對象,并通過這個對象從客戶端獲得發送過來的字節流(注意,一定要用字節流,因為,上傳的文件可能是二進制文件,如圖象文件,因此,使用字節流會更通用)。并將這些字節流保存在D盤的out.txt文件中。然后我們打開out.txt,文件的內容如圖1所示:



                                                                                              圖1

        由于out.txt是使用文本形式打開的,并且file1上傳的是a.jpg(一個圖象文件),因此,顯示的是一些亂碼。我們可以不用管它們。只需要看看這些內容的頭部。我們很快就可以找到規律。每一個文件內容的頭部都由“-----------------------------30514443229777”分隔,然后是這個文件的屬性,如下:

    Content-Disposition: form-data; name="file1"; filename="a.jpg"

    Content-Type: image/jpeg

    其中包含了文件選擇框的name屬性,還有上傳的文件名(filename字段),要注意的,firefox在上傳時,這個filename屬性值只是文件名,如果使用IE,就是帶路徑的文件名,如D:"a.jpg

    接下來的規則就和HTTP的頭一樣了,以一個空行("r"n)分隔。后面就是文件的具體內容。現在最關鍵的文件的結尾,從圖1可以看出,文件的結尾也是“-----------------------------30514443229777”,因此,可以斷定,第一個上傳的文件(包括文件頭)是夾在兩個“-----------------------------30514443229777”之間的。而“-----------------------------30514443229777”就是multipart/form-data協議的分隔符。但這里還有一個最關鍵的問題。這個分隔符每次上傳都不一樣,服務端是如何知道每次上傳的這個分隔符的呢?

    實際上,這個分隔符是通過HTTP請求頭的Content-Type字段獲得,可通過下面的代碼輸出這個字段值:

    System.out.println(request.getHeader("Content-type"));

    輸出的內容如下:

    multipart/form-data; boundary=---------------------------106712230227687

    只要在服務端獲得boundary后面的值即可。經過測試,Content-Type中的分隔符號中的“-”比實際上傳的“-”少兩個,不知是怎么回事。不過這沒關系,我們可以認為每一個文件塊是以""r"n—“結尾的,或是直接將從boundary獲得的分隔符加兩個“”。而最后結尾的分隔符是“---------------------------106712230227687—”,后面多了兩個“”。

    綜合上述,也就是說,一個文件塊是以“---------------------------106712230227687”開頭,以“”結尾,從圖2可以看出這一切。



                                      圖2

        至于剩下的工作,就是按著上面的規則來分析這些字符流了。分析的方法很多。在這里就不詳述了。

    multipart/form-data規 范原文:http://www.ietf.org/rfc/rfc2388.txt

    Form-based File Upload in HTML:http://www.ietf.org/rfc/rfc1867.txt






    Android開發完全講義(第2版)(本書版權已輸出到臺灣)

    http://product.dangdang.com/product.aspx?product_id=22741502



    Android高薪之路:Android程序員面試寶典 http://book.360buy.com/10970314.html


    新浪微博:http://t.sina.com.cn/androidguy   昵稱:李寧_Lining

    posted on 2008-05-29 12:42 銀河使者 閱讀(6781) 評論(1)  編輯  收藏 所屬分類: javaweb 原創

    評論

    # re: Web上傳文件的原理及實現  回復  更多評論   

    ASP有沒有辦法直接獲取上傳文件部分的內容?
    2009-11-27 11:00 | 網絡監控
    主站蜘蛛池模板: 亚洲风情亚Aⅴ在线发布| 亚洲AV无码一区二区三区人| 男女猛烈xx00免费视频试看| 在线中文高清资源免费观看| 亚洲www77777| 免费欧洲美女牲交视频| 亚洲第一街区偷拍街拍| 国产一级淫片免费播放| 在线观看亚洲专区| 亚洲无线一二三四区手机| fc2免费人成在线| 亚洲成人精品久久| 91成人免费观看| 亚洲va成无码人在线观看| 性一交一乱一视频免费看| 久久亚洲AV成人无码国产电影| 日本一线a视频免费观看| jzzijzzij在线观看亚洲熟妇| 亚洲第一黄色网址| 国产永久免费高清在线| 91亚洲国产成人久久精品网站| 免费人成在线观看69式小视频| 亚洲一本到无码av中文字幕| 免费人成在线观看播放国产| 中文字幕在线免费视频| 99久久精品国产亚洲| 免费看片免费播放| 九一在线完整视频免费观看| 亚洲VA中文字幕无码毛片| 亚洲最大免费视频网| 美女扒开尿口给男人爽免费视频 | 91福利免费视频| 亚洲欧美成人一区二区三区| 国产成人精品久久亚洲高清不卡 | 欧洲人免费视频网站在线| 亚洲av午夜精品无码专区| 亚洲国产成人精品久久久国产成人一区二区三区综 | 亚洲情A成黄在线观看动漫软件| 午夜国产大片免费观看| 三年片在线观看免费观看大全一 | 亚洲综合无码一区二区|