欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java動態(tài)顯示文件上傳進(jìn)度實(shí)現(xiàn)代碼

 更新時間:2022年06月23日 17:10:06   作者:fuzhouxufeng  
這篇文章主要為大家詳細(xì)介紹了Java動態(tài)顯示文件上傳進(jìn)度實(shí)現(xiàn)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實(shí)例實(shí)現(xiàn)文件上傳的進(jìn)度顯示,我們先看看都有哪些問題我們要解決。

1 上傳數(shù)據(jù)的處理進(jìn)度跟蹤
2 進(jìn)度數(shù)據(jù)在用戶頁面的顯示

就這么2個問題,
第一個問題,主要是組件的選擇
必須支持?jǐn)?shù)據(jù)處理偵聽或通知的組件。當(dāng)然,我肯定只用我自己的組件啦?;驹硎?/p>

1 使用request.getContentLength() 讀取到處理數(shù)據(jù)的總長度,注意這個長度不等于文件的長度,因為Base64等編碼會增加數(shù)據(jù)量,如果超過了允許的長度,直接返回-1;

2 在每讀取一部分?jǐn)?shù)據(jù)時(比如一行,或者64K,或者你自定義的字節(jié)數(shù)),將讀取的字節(jié)數(shù)通知我們的進(jìn)度跟蹤程序。我取名為 UploadListener代碼如下

/*
* 處理附件上傳的通知。

* 各位可以繼承這個類,來實(shí)現(xiàn)自己的特殊處理。 
* 
* @author 趙學(xué)慶 www.java2000.net 
*/ 
 public class UploadListener ... { 
 // 調(diào)試模式將在控制臺打印出一些數(shù)據(jù) 
 private boolean debug;

 // 總數(shù)據(jù)字節(jié)數(shù) 
 private int total;

 // 當(dāng)前已經(jīng)處理的數(shù)據(jù)字節(jié)數(shù) 
 private int totalCurrent = 0 ;

 // 延遲,用來調(diào)試用,免得速度太快,根本卡看不到進(jìn)度 
 private int delay = 0 ;

 /** */ /** 
 * 處理數(shù)據(jù)通知的方法。

 * 保存已經(jīng)處理的數(shù)據(jù)。并且在一定的比例進(jìn)行延遲。默認(rèn)每1%

 * 如果不需用延遲,可以刪掉內(nèi)部的代碼,加快速度。 
 * 
 * @param size 增加的字節(jié)數(shù) 
 */ 
 public void increaseTotalCurrent( long size) ... { 
 this .totalCurrent += size; 
 try ... { 
 currentRate = totalCurrent * 100 / total; 
  if (currentRate > lastRate) ... { 
  if (delay > 0 ) ... { 
  Thread.sleep(delay); 
  } 
  if (debug) ... { 
  System.out.println( " rate= " + totalCurrent + " / " + total + " / " + (totalCurrent * 100 / total)); 
  } 
  lastRate = currentRate; 
 } 
 } catch (Exception e) ... { 
 e.printStackTrace(); 
 } 
 } 

 /** */ /** 
 * 讀取全部自己數(shù) 
 * 
 * @return 
 */ 
 public int getTotal() ... { 
 return total; 
 } 

 /** */ /** 
 * 讀取已經(jīng)處理的字節(jié)數(shù) 
 * 
 * @return 
 */ 
 public int getTotalCurrent() ... { 
 return totalCurrent; 
 } 

 private long lastRate = 0 ;

 private long currentRate = 0 ;

 public int getDelay() ... { 
 return delay; 
 } 

 public void setDelay( int delay) ... { 
 this .delay = delay; 
 } 

 public void setTotal( int total) ... { 
 this .total = total; 
 } 

 public boolean isDebug() ... { 
 return debug; 
 } 

 public void setDebug( boolean debug) ... { 
 this .debug = debug; 
 } 
}

3 下面我們來看上傳的處理部分

 Upload upload = new Upload(request); 
 // 增加了偵聽進(jìn)度的代碼 
 UploadListener uploadListener = new UploadListener(); 
 // 這句話我們后面再討論,這個可是關(guān)鍵 
 session.setAttribute( " uploadListener " ,uploadListener); 
 uploadListener.setDelay( 0 ); 
 uploadListener.setDebug( true ); 
 upload.setUploadListener(uploadListener); 
 upload.parse(); 
 // 這句話同樣重要,我們后面再討論 
 session.setAttribute( " uploadListener " , null );

4 我們再看上傳的表單部分

< script. type = " text/javascript. " > 
 function checkForm() ... { 
 $( " SHOW_FRAME. " ).src = " link.jsp " ; 
 $( ' SUBMIT ' ).disabled = true ; 
 Ext.MessageBox.show( ... { 
 title: ' Please wait... ' , 
 msg: ' Initializing... ' , 
 width: 240 , 
 progress: true , 
 closable: false 
 } ); 
 $( " MAIN_FORM. " ).submit(); 
 return false ; 
} 
 function setUploadProcess(total,current) ... { 
 var rate = Number(current) / Number(total); 
 Ext.MessageBox.updateProgress(rate, ' Uploading... ' + current + " / " + total); 
 if (Number(current) >= Number(total)) ... { 
 closeUploadProcess(); 
 } 
} 
 function closeUploadProcess() ... { 
 Ext.MessageBox.hide(); 
} 
</ script. > 
< iframe. name = " ACTION_FRAME. " id = " ACTION_FRAME. " width = " 0 " height = " 0 " ></ iframe. > 
< iframe. name = " SHOW_FRAME. " id = " SHOW_FRAME. " width = " 0 " height = " 0 " ></ iframe. > 
< form. method = " OST " id = " MAIN_FORM. " nsubmit = " return checkForm() " enctype = " multipart/form-data " 
 action = " uploadFileSave.jsp " target = " ACTION_FRAME. " > 
 < input type = " file " size = " 50 " name = " file " > 
 < input type = " submit " ID = " SUBMIT " value = " Upload It " > 
</ form. >

第一個iframe用于提交表單數(shù)據(jù),第二個就是我們用來獲取處理數(shù)據(jù)進(jìn)度信息的。
提交表單很簡單,target指向了我們的第一個iframe.
我們看一下JS
checkForm. 里面第一句就是關(guān)鍵的讀取進(jìn)度信息的頁面,我們在第二個iframe里面獲得。然后就是彈出進(jìn)度的顯示框,我使用了Ext. 然后提交上傳表單
setUploadProcess 用來更新進(jìn)度框上面的數(shù)據(jù),第一個參數(shù)是數(shù)據(jù)總共的大小,第二個參數(shù)是已經(jīng)處理的大小。
closeUploadProcess 關(guān)閉進(jìn)度框

5 最后,我們來看讀取進(jìn)度信息的頁面

<% @ page language = " java " contentType = " text/html; charset=utf-8 " pageEncoding = " utf-8 " %> 
<% @include file = " ../package.inc.jsp " %> 
<% 
 response.setHeader( " ragma " , " no-cache " ); 
 response.setHeader( " Cache-Control " , " no-cache " ); 
 response.setDateHeader( " Expires " , 0 ); 
 response.setBufferSize( 0 ); 
 UploadListener uploadListener = null ; 
 while (uploadListener == null || uploadListener.getTotalCurrent() <= 0 ) ... { 
 uploadListener = (UploadListener) session.getAttribute( " uploadListener " ); 
 out.print( " . " ); 
 out.flush(); 
 Thread.sleep( 10 ); 
 } 
 long total = uploadListener.getTotal(); 
 out.println(total); 
 long current; 
 out.flush(); 
 while ( true ) ... { 
 current = uploadListener.getTotalCurrent(); 
 if (current >= total) ... { 
 break ; 
 } 
 out.println( " <script. type='text/javascript'>parent.setUploadProcess(' " + total + " ',' " + current + " ');</script> " ); 
 out.flush(); 
 Thread.sleep( 10 ); 
 } 
%>< script. type = " text/javascript. " > parent.closeUploadProcess(); </ script. >

其中前面的循環(huán),用來判斷是否產(chǎn)生了上傳的信息,如果沒有則等待。

然后就是讀取上傳的信息,并計算后生成調(diào)用上級窗口的更新進(jìn)度條的JS, 請注意out.print后面必須跟上out.flush,否則不會持續(xù)輸出到客戶端,也就不會看到連續(xù)的進(jìn)度條變化。

總結(jié):

上面的部分比較亂,我這里總結(jié)一下關(guān)鍵點(diǎn)。

1、在上傳組件里面,把總大小和當(dāng)前讀取了的大小放到一個類里面,并持續(xù)更新,直到處理完畢
2、上傳的進(jìn)度類,放在session里面,供進(jìn)度讀取頁面讀取
3、進(jìn)度讀取頁面,從session里面拿到數(shù)據(jù),并返回結(jié)果。

有幾個疑問解釋一下。

1、由于Http協(xié)議決定了,必須等request處理完畢才會返回輸出,所以不能在upload頁面里進(jìn)行處理進(jìn)度的顯示。我前面測試到1M左右的文件不成功,就是沒有考慮到這個問題。所以必須單獨(dú)用一個GET的程序進(jìn)行讀取
2、讀取是一個持續(xù)不斷的過程,因為上傳大文件是很慢的!
3、如果你的應(yīng)用服務(wù)器啟用了GZIP壓縮,是容器管理的,那么很不幸,因為容易必須拿到所有的數(shù)據(jù),至少是一部分?jǐn)?shù)據(jù)才會返回,所以造成我們返回的那些很少的字節(jié)經(jīng)常會被截住,造成無法顯示上傳的連續(xù)過程。  

解決方法

1) 關(guān)閉GZIP, 我想許多人不會這么做 
2) 使用自定義的GZIP壓縮,判斷某些東西(比如URL),對他們不進(jìn)行壓縮處理

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java請求轉(zhuǎn)發(fā)和請求重定向區(qū)別詳解

    Java請求轉(zhuǎn)發(fā)和請求重定向區(qū)別詳解

    這篇文章主要介紹了Java請求轉(zhuǎn)發(fā)和請求重定向區(qū)別詳解,請求轉(zhuǎn)發(fā)和請求重定向,但二者是完全不同的,所以我們今天就來盤他們的區(qū)別介紹,需要的朋友可以參考一下
    2022-07-07
  • 詳解Java中native方法的使用

    詳解Java中native方法的使用

    native是與C++聯(lián)合開發(fā)的時候用的!使用native關(guān)鍵字說明這個方法是原生函數(shù),也就是這個方法是用C/C++語言實(shí)現(xiàn)的,并且被編譯成了DLL,由java去調(diào)用。本文給大家介紹java 中native方法使用,感興趣的朋友一起看看吧
    2020-09-09
  • java學(xué)習(xí)之jar包的下載和導(dǎo)入

    java學(xué)習(xí)之jar包的下載和導(dǎo)入

    我們經(jīng)常碰到有些jar包在中央倉庫沒有的情況,這時候我們需要導(dǎo)入,這篇文章主要給大家介紹了關(guān)于java學(xué)習(xí)之jar包的下載和導(dǎo)入的相關(guān)資料,需要的朋友可以參考下
    2023-06-06
  • Spring Security實(shí)現(xiàn)基于角色的訪問控制框架

    Spring Security實(shí)現(xiàn)基于角色的訪問控制框架

    Spring Security是一個功能強(qiáng)大的安全框架,提供了基于角色的訪問控制、身份驗證、授權(quán)等安全功能,可輕松保護(hù)Web應(yīng)用程序的安全,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-04-04
  • java實(shí)現(xiàn)兩臺服務(wù)器間文件復(fù)制的方法

    java實(shí)現(xiàn)兩臺服務(wù)器間文件復(fù)制的方法

    這篇文章主要介紹了java實(shí)現(xiàn)兩臺服務(wù)器間文件復(fù)制的方法,是對單臺服務(wù)器上文件復(fù)制功能的升級與改進(jìn),具有一定參考借鑒價值,需要的朋友可以參考下
    2015-01-01
  • Java中的位運(yùn)算符全解

    Java中的位運(yùn)算符全解

    這篇文章主要為大家詳細(xì)介紹了Java中的位運(yùn)算符,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • JFinal極速開發(fā)框架使用筆記分享

    JFinal極速開發(fā)框架使用筆記分享

    下面小編就為大家分享一篇JFinal極速開發(fā)框架使用筆記,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • Java中超高頻常見字符操作合集(建議收藏)

    Java中超高頻常見字符操作合集(建議收藏)

    這篇文章主要為大家詳細(xì)介紹了Java中超高頻常見字符操作合集,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)java有一定的幫助,需要的小伙伴可以參考下
    2023-10-10
  • Java pdf和jpg互轉(zhuǎn)案例

    Java pdf和jpg互轉(zhuǎn)案例

    這篇文章主要介紹了Java pdf和jpg互轉(zhuǎn)案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Java 高并發(fā)二:多線程基礎(chǔ)詳細(xì)介紹

    Java 高并發(fā)二:多線程基礎(chǔ)詳細(xì)介紹

    本文主要介紹Java 高并發(fā)多線程的知識,這里整理詳細(xì)的資料來解釋線程的知識,有需要的學(xué)習(xí)高并發(fā)的朋友可以參考下
    2016-09-09

最新評論