day19
public class UploadServlet extends HttpServlet {
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 使用commons-fileupload實現文件上傳
ServletContext sc=req.getServletContext();
String tempPath=sc.getRealPath("/temp");// 臨時文件夾的絕對路徑
// 1.創建一個FileItem的工廠
// sizeThreshold 內存緩衝區的大小,以位元組為單位,如果上傳的文件小於內存緩衝區的大小,那麼使用內存進行緩衝
// repository 代表硬碟上的緩存文件夾的位置,如果上傳的文件大於內存緩衝區的大小,將使用硬碟進行緩存,緩存文件存在緩存文件夾中
DiskFileItemFactory factory=new DiskFileItemFactory(1024*1024, new File(tempPath));
// 2. 創建上傳文件的核心工具類->對文件上傳的各類參數進行配置
ServletFileUpload fileUpload=new ServletFileUpload(factory);
// 判斷當前請求是否是一個文件上傳的請求
if(!fileUpload.isMultipartContent(req)){
throw new RuntimeException("請使用正確的文件上傳表單");
}
// 解決上傳的文件名的亂碼問題
fileUpload.setHeaderEncoding("utf-8");
// 設置文件上傳的大小限制
// 設置每個文件的大小限制(byte)
//fileUpload.setFileSizeMax(1024);
// 設置一次請求中所有上傳的文件的總大小(byte)
//fileUpload.setSizeMax(1024*10);
// 設置一個文件上傳的監聽器
// 限制fileUpload已經綁定了程序員提供的ProgressListener的實現類
// 每當fileUpload發生了文件上傳狀態的改變,就會主動調用監聽器的update方法
fileUpload.setProgressListener(new ProgressListener() {
private long startTime=System.currentTimeMillis();//設置當前時間為開始時間
@Override
public void update(long pBytesRead, long pContentLength, int pItems) {
// pBytesRead-代表當前已經讀取(上傳)的位元組數
// pContentLength-當前上傳文件的總長度
// pItems-當前FileItem的編號
//System.out.println("已經上傳:"+pBytesRead/1024+"kb,文件總長度:"+pContentLength/1024+"kb,item編號:"+pItems);
// 當前上傳的百分比 pBytesRead/pContentLength
// 0.0121132 *10000 121.132-round->121/100.0 1.21
// double pre=Math.round(pBytesRead*10000.0/pContentLength)/100.0;
// System.out.println("當前上傳進度為:"+pre+"%");
// 上傳速度 pBytesRead/耗時
// 當前時間
long currentTime=System.currentTimeMillis();
long cost=(currentTime-startTime)/1000;// 上傳消耗的時間 s
long speed=cost==0?0:(pBytesRead/(1024*1024))/cost;// byte/ms kb/s
System.out.println("上傳速度為:"+speed+"mb/s");
}
});
try {
// 調用fileUpload的parseRequest方法,對請求實體內容進行解析
// 該方法會將每個input的內容封裝成一個FileItem對象
// FileItem對象即可能是一個普通的表單參數,也可能是上傳的文件
List<FileItem> list=fileUpload.parseRequest(req);
if(list!=null){
for(FileItem item:list){
if(item.isFormField()){
// 當前FileItem封裝的是普通的表單參數
String name=item.getFieldName();//獲取input的name屬性的值
// 解決普通表單參數的亂碼問題
String value=item.getString("utf-8");// 獲取input的值
System.out.println("name="+name+"~~~value="+value);
}else{
// 說明當前FileItem是一個文件,通過io流將文件寫到upload文件夾中
InputStream is=item.getInputStream();
FileOutputStream fos=null;
// 獲取上傳文件的文件名
String fileName=item.getName();
// 解決ie瀏覽器的文件名bug
if(fileName.contains("")){
// 說明文件名中有路徑 C:UsersAdministratorDesktopaaa.txt
fileName=fileName.substring(fileName.lastIndexOf("")+1);
}
// 解決文件名重複的問題 UUID
String saveName=UUID.randomUUID().toString()+"_"+fileName;
// 解決文件都存放在同一個文件夾下的問題->使用文件名的hashcode的16進位表示來生成中間路徑
// 獲取文件名的hashCode值的16進位表示
String hashStr=Integer.toHexString(saveName.hashCode());
// 進行補0操作
while(hashStr.length()<8){
hashStr="0"+hashStr;
}
// 根據hashStr生成中間路徑
String midPath="/";
for(int i=0;i<hashStr.length();i++){
midPath=midPath+hashStr.charAt(i)+"/";
}
// sc.getRealPath("/WEB-INF/upload/7/7/b/5/3/b/f/7/")
// D:/web/tomcat7/webapps/day19/WEB-INF/upload/7/7/b/5/3/b/f/7
String savePath=sc.getRealPath("/WEB-INF/upload"+midPath);
// 在硬碟上生成對應的文件夾
File dir=new File(savePath);
dir.mkdirs();// 在硬碟上直接創建對應的文件夾
fos=new FileOutputStream(savePath+"/"+saveName);
byte[] array=new byte[1024];
int len=is.read(array);
while(len!=-1){
fos.write(array, 0, len);
len=is.read(array);
}
// 先關文件輸入流
is.close();
// 刪除該上傳文件的緩存數據,包括臨時文件夾中的臨時文件
item.delete();
fos.close();
}
}
}
} catch (FileUploadException e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
// String name=req.getParameter("name");
// String addr=req.getParameter("addr");
// System.out.println("name="+name);
// System.out.println("addr="+addr);
// 通過req獲取讀取請求實體內容的位元組流
// ServletInputStream sis=req.getInputStream();
// // 創建位元組數組,作為輸入流讀取時使用的緩衝空間
// byte[] array=new byte[10];
// // 調用輸入流的read方法,將流中的數據讀入到緩衝空間,返回本次讀取到的byte的長度
// int len=sis.read(array);
// // 當len!=-1,說明流中仍有數據沒讀取
// while(len!=-1){
// // 將緩衝空間的內容以字元串形式輸出到控制台
// System.out.print(new String(array,0,len));
// // 再次讀取流中的內容
// len=sis.read(array);
// }
}
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doPost(req,resp);
}
}
推薦閱讀:
※速度收藏!國內手機號段的最全整理!
※新一代奧迪Q7競爭力分析 以科技武裝豪華
※谷歌又來造福AI學者了:數據增強也能自動化!
※Kaggle項目:泰坦尼克號生存預測
※墨西哥利用無人機,把犯罪率降低了10%