看書上(JSP應用與開發技術)使用JSP檔案上傳,寫了個真無語,壓根就有很多問題,上傳500KB的檔案傳過去後只剩350KB,而且編碼必須是GBK、GB2312,否則傳過去的檔案都資料截取不正確。
琢磨了許久,發現問題出在
int startPos = ((file.substring(0,pos)).getBytes()).length;
//取得檔案資料的結束的位置
int endPos =((file.substring(0,boundaryLocation)).getBytes()).length;
這裡,問題就是根據字串擷取的位元組數,然後從位元組數組裡截取根本就不正確。而後自己實現了個,不用字串位元組,而是自己以位元組找位元組。如下:
UploadTelRecord.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@page import="java.io.DataInputStream"%><%@page import="java.io.FileOutputStream"%><%@page import="java.io.File"%><%@page import="java.net.URLEncoder" %><!-- 上傳通話錄音檔案 --><%! //在位元組數組裡尋找某個位元組數組,找到返回>=0,未找到返回-1 private int byteIndexOf(byte[] data,byte[] search,int start) { int index=-1; int len=search.length; for(int i=start,j=0;i<data.length;i++) { int temp=i; j=0; while(data[temp]==search[j]) { System.out.println((j+1)+",值:"+data[temp]+","+search[j]); //計數 j++; temp++; if(j==len) { index=i; return index; } } } return index; }%><%String getAction=request.getParameter("action");if(getAction!=null&&(getAction.equals("upload"))) //上傳檔案{ //定義上傳的最大檔案位元組數1M int MAX_SIZE=1024000; String rootPath; DataInputStream in=null; FileOutputStream fileOut=null; String remoteAddr=request.getRemoteAddr(); String serverName=request.getServerName(); String realPath=request.getRealPath("/"); realPath=realPath.substring(0,realPath.lastIndexOf("\\")); //設定儲存檔案的目錄 rootPath=realPath+ "\\upload\\telRecord\\"; //取得用戶端上傳的資料類型 String contentType=request.getContentType(); try{ if(contentType.indexOf("multipart/form-data")>=0){ in=new DataInputStream(request.getInputStream()); int formDataLength=request.getContentLength(); if(formDataLength>MAX_SIZE) { out.println("0,檔案大小超過系統限制!"); out.flush(); return; } //儲存上傳的檔案資料 byte dateBytes[]=new byte[formDataLength]; int byteRead=0; int totalRead=0; while(totalRead<formDataLength) { byteRead=in.read(dateBytes,totalRead,formDataLength); totalRead+=byteRead; } String data=new String(dateBytes,"UTF-8"); //取得上傳的檔案名稱 String saveFile=data.substring(data.indexOf("filename=\"")+10); saveFile=saveFile.substring(0,saveFile.indexOf("\n")); saveFile=saveFile.substring(saveFile.lastIndexOf("\\")+1,saveFile.indexOf("\"")); //取得資料分割字串 int lastIndex=contentType.lastIndexOf("="); //資料分割線開始位置boundary=--------------------------- String boundary=contentType.substring(lastIndex+1,contentType.length());//---------------------------257261863525035 //計算開頭資料頭佔用的長度 int startPos; startPos=byteIndexOf(dateBytes,"filename=\"".getBytes(),0); startPos=byteIndexOf(dateBytes,"\n".getBytes(),startPos)+1; //遍曆掉3個分行符號到資料區塊 startPos=byteIndexOf(dateBytes,"\n".getBytes(),startPos)+1; startPos=byteIndexOf(dateBytes,"\n".getBytes(),startPos)+1; //邊界位置 int endPos=byteIndexOf(dateBytes,boundary.getBytes(),(dateBytes.length- startPos))-4; //建立檔案 String fileName=rootPath+saveFile; File checkFile=new File(fileName); if(checkFile.exists()){ out.println("0,檔案已經存在!"); out.flush(); return; } File fileDir=new File(rootPath); if(!fileDir.exists()) fileDir.mkdirs(); //寫入檔案 fileOut=new FileOutputStream(fileName); fileOut.write(dateBytes,startPos,(endPos-startPos)); fileOut.flush(); out.println("檔案上傳成功!儲存在:"+fileName); } else { out.println("0,未找到上傳檔案!"); out.flush(); return; } }catch(Exception error) { out.println("發生異常:"+error.getMessage()); } finally { try { if(in!=null) in.close(); if(fileOut!=null) fileOut.close(); }catch(Exception e ){} } out.println("<br><br>"); out.println("<a href='UploadTelRecord.jsp'>繼續上傳</a>"); return;}%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>上傳通話記錄</title> </head> <body style="margin:50px;"> <p>請選擇您要上傳的通話錄音檔案,檔案命名格式為:通話時間_手機號_連絡人姓名.尾碼,沒有連絡人姓名請置空,如: 111213123123_10086_中國移動.amr,沒有姓名則為111213123123_10086_.amr</p> <form method="POST" action="UploadTelRecord.jsp?action=upload" ENCTYPE="multipart/form-data"> <input type="file" name="file1" size="30"><br/> <input type="submit" value="開始上傳"> </form> </body></html>