文件上傳前檢測客戶端文件大小的三種方法


前段時間,因工作需要,需要在文件上傳時限制文件的大小,所以需要在上傳之前檢測文件的大小。

 

方法一:js檢測文件大小

一開始的想法是通過js直接在前端檢測文件大小,代碼如下:

//獲取上傳文件大小
function getFileSize(filePath)
{
    var vBrowserVersion = getBrowserVersion();
    if("MSIE6.0" == vBrowserVersion){//對於IE6,使用Image的fileSize屬性進行判斷文件大小
           var image=new Image();
           image.dynsrc=filePath;
          return image.fileSize;
    }else if(vBrowserVersion.indexOf("MSIE")>=0){//對於IE6以上瀏覽器(IE6是公司默認最低版本),使用ActiveXObject進行上傳
        var fso = new ActiveXObject("Scripting.FileSystemObject");
        return fso.GetFile(filePath).size;
    }else{//其它的瀏覽器,也是采用Image的fileSize屬性進行判斷文件大小
           var image=new Image();
           image.dynsrc = filePath;
          return image.fileSize;
    }
}

但這種方法存在一些弊端:

1、IE6下面是利用的Image標簽的dynsrc屬性去判斷;

2、IE8下面使用ActiveXObject進行上傳的話,是IE安全機制不支持的,需要降低本地瀏覽器的安全設置,對於開發者來說,是不可能去限制用戶的。

故這種方法不可行。

 

方法二:java讀取文件流方式

接着的一種做法是通過dwr的方式,將文件路徑傳到后台去,再去讀取文件的大小。代碼如下:

 1 /**
 2      * 讀取單據所帶的附件總大小
 3      * 
 4      * @param filaPath 准備上傳的文件的路徑
 5      * @param moduleKey 文件對象類型
 6      * @param moduleObjectId 文件對象ID
 7      * @return lAttachmentTotalSize 該單據的附件總大小
 8      * @throws AttachmentException
 9      */
10     public static long getAttachmentTotalSize(String filePath, String moduleKey, String moduleObjectId)
11         throws AttachmentException {
12         // 附件總大小
13         long lAttachmentTotalSize = 0;
14         // 准備上傳的文件大小
15         long lAttachmentSize = 0;
16         // 已經保存的附件的大小
17         long lExistAttachmentSize = 0;
18         FileInputStream fis = null;
19         // 根據對象類型和對象ID查詢出已經保存的附件
20         List lstAttachment = queryAttachmentList(moduleKey, moduleObjectId);
21         if (null != lstAttachment && lstAttachment.size() > 0) {
22             for (int i = 0, iSize = lstAttachment.size(); i < iSize; i++) {
23                 AttachmentVO vo = (AttachmentVO) lstAttachment.get(i);
24                 // 讀取附件的大小,並累加
25                 lExistAttachmentSize += vo.getFileSize();
26             }
27         }
28         // 根據filePath讀取准備上傳的文件大小,與已經保存的文件大小相加
29         try {
30             File ff = new File(filePath);
31             if (ff.exists()) {
32                 fis = new FileInputStream(ff);
33                 lAttachmentSize = fis.available();
34             } else {
35                 logger.error("AttachmentUtil.getAttachmentTotalSize方法,獲取准備上傳的文件時,文件不存在");
36             }
37         } catch (IOException ex) {
38             logger.error("AttachmentUtil.getAttachmentTotalSize方法,讀取文件大小時發生異常", ex);
39         } finally {
40             // 關閉流
41             try {
42                 if (null != fis) {
43                     fis.close();
44                 }
45             } catch (IOException ex) {
46                 logger.error("關閉流時發生異常", ex);
47             }
48         }
49         // 附件總大小=已經存在的附件大小+准備上傳的附件大小
50         lAttachmentTotalSize = lExistAttachmentSize + lAttachmentSize;
51         return lAttachmentTotalSize;
52     }

這個方法也存在一些弊端:

1、服務器端在讀取文件路徑時,是訪問不了客戶端的文件的,它只會放在服務器端自己對應路徑下的文件,但往往這個路徑下是不存在對應文件的,故讀取出來的文件大小總為0;

2、IE8下由於安全問題,服務端獲取客戶端文件的路徑,會變為C:/fakePath問題,這個問題在下一篇文章中會有解決方案;

 

方法三:Ajax異步提交表單獲取文件大小

最后采取的一種方法是,通過Ajax進行異步的表單提交,因為form里面使用了file標簽,是可以拿到文件的大小的。代碼如下:

 1 //定義ajax異步提交form時需要的參數
 2                     var options = {
 3                         url:'<common:webRoot/>/product/attachment/attachmentMultiAction.do?queryType=getAttachmentTotalSize',
 4                         success:successReturn,
 5                         type:'post'
 6                     };
 7                     //ajax異步提交form
 8                     jQuery("#attachmentForm").ajaxSubmit(options);
 9 
10 
11 
12 //ajax返回后回調方法
13         function successReturn(data){
14             //后台返回的消息固定為FileTooLarge
15             if("FileTooLarge" == data){
16                 var vMessage = "您添加的附件文件總大小超過(<%=AttachmentInfo.ATTACHMENT_SIZE/1024/1024%>M),請壓縮文件或者重新選擇。";
17                 alert(vMessage);
18             }else{//返回消息為空時,則正常提交form,上傳文件
19                 document.attachmentForm.target = "_self";
20                 document.attachmentForm.action = "<common:webRoot/>/product/attachment/attachmentMultiAction.do";
21                 document.attachmentForm.submit();
22                 window.loadingImg.style.visibility = "visible";
23             }
24         }

其中successReturn是返回后調用的方法,如果文件過大則進行提示,否則重新提交,進行上傳。

關於Ajax異步提交表單的詳細介紹,會在下一篇文章中介紹。

這種方法的好處是不受客戶端和服務器端的安全性影響,不好的地方是會先進行一個異步提交,需要消耗一定資源,當然因為是異步的,只要不是上傳特別大的附件而導致檢測過程過長,頁面端的響應效果還是沒什么太大的影響。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM