web端基於java的文件上傳下載

web端的文件上傳和下載

在Web應用系統開發中,文件上傳和下載功能是非常常用的功能,今天來講一下JavaWeb中的文件上傳和下載功能的實現。

  對於文件上傳,瀏覽器在上傳的過程中是將文件以流的形式提交到服務器端的,如果直接使用Servlet獲取上傳文件

的輸入流然後再解析裏面的請求參數是比較麻煩,所以一般選擇採用apache的開源工具common-fileupload這個文件上

傳組件。這個common-fileupload上傳組件的jar包可以去apache官網上面下載,也可以在struts的lib文件夾下面找到,

struts上傳的功能就是基於這個實現的。common-fileupload是依賴於common-io這個包的,所以還需要下載這個包。

對於此包可以自己搜索,資源很多。

1.上傳文件邏輯

下面寫下邏輯層的代碼:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

HttpSession session = request.getSession(); 
String fileExtName = null;
String realSavePath = null;
    String saveFilename = null;
    int  filesize = 0;
/*得到上傳文件的保存目錄,將上傳的文件存放於WEB-INF目錄下,不允許外界直接訪問,保證上傳文件的安全*/
String savePath = request.getSession().getServletContext().getRealPath("/WEB-INF/upload");
/*上傳時生成的臨時文件保存目錄*/
String tempPath = request.getSession().getServletContext().getRealPath("/WEB-INF/temp");
File tmpFile = new File(tempPath);
if (!tmpFile.exists()) {
/*創建臨時目錄*/
tmpFile.mkdir();
}
   try{
                /*使用Apache文件上傳組件處理文件上傳步驟:
                1、創建一個DiskFileItemFactory工廠*/
                DiskFileItemFactory factory = new DiskFileItemFactory();
                /*設置工廠的緩衝區的大小,當上傳的文件大小超過緩衝區的大小時,就會生成一個臨時文件存放到指定的臨時目錄當中。*/
                factory.setSizeThreshold(1024*100);
                /*設置緩衝區的大小爲100KB,如果不指定,那麼緩衝區的大小默認是10KB
                設置上傳時生成的臨時文件的保存目錄*/
                factory.setRepository(tmpFile);
                ServletFileUpload upload = new ServletFileUpload(factory);
                upload.setProgressListener(new ProgressListener(){
                    public void update(long pBytesRead, long pContentLength, int arg2) {
                        System.out.println("文件大小爲:" + pContentLength + ",當前已處理:" + pBytesRead);
                        /**
                        
                         */
                    }
                });
                /**
                解決上傳文件名的中文亂碼
                 */
                upload.setHeaderEncoding("UTF-8"); 
                request.setCharacterEncoding("UTF-8");
                /**
                3、判斷提交上來的數據是否是上傳表單的數據       
                設置上傳單個文件的大小的最大值,目前是設置爲1024*1024字節,也就是1MB
                 */               
                upload.setFileSizeMax(1024*1024*100);
                /**設置上傳文件總量的最大值,最大值=同時上傳的多個文件的大小的最大值的和,目前設置爲10MB*/
                upload.setSizeMax(1024*1024*1000);
                /**4、使用ServletFileUpload解析器解析上傳數據,解析結果返回的是一個List<FileItem>集合,每一個FileItem對應一個Form表單的輸入項*/
                List<FileItem> list = upload.parseRequest(request);
                for(FileItem item:list){
                filesize=(int) list.get(0).getSize();
                 /**  filesize=parse(int)list.size();*/
                    /**如果fileitem中封裝的是普通輸入項的數據*/
                    if(item.isFormField()){
                        String name = item.getFieldName();
                        /**解決普通輸入項的數據的中文亂碼問題*/                       
                        String value = item.getString("UTF-8");
                        System.out.println(name + "=" + value);
                    }else{
                        String filename = item.getName();
                        if(filename==null || filename.trim().equals("")){
                            continue;
                        }
                       /**注意:不同的瀏覽器提交的文件名是不一樣的,有些瀏覽器提交上來的文件名是帶有路徑的,如:  c:\a\b\1.txt,而有些只是單純的文件名,如:1.txt
                       處理獲取到的上傳文件的文件名的路徑部分,只保留文件名部分*/
                        filename = filename.substring(filename.lastIndexOf("\\")+1);
                        /**得到上傳文件的擴展名*/
                        fileExtName = filename.substring(filename.lastIndexOf(".")+1);
                        /**如果需要限制上傳的文件類型,那麼可以通過文件的擴展名來判斷上傳的文件類型是否合法
                        獲取item中的上傳文件的輸入流*/
                        InputStream in = item.getInputStream();
                        /**得到文件保存的名稱*/
                        saveFilename = makeFileName(fileExtName);
                        /**得到文件的保存目錄*/
                      realSavePath = makePath(saveFilename, savePath);
                        /**創建一個文件輸出流*/
                        FileOutputStream out = new FileOutputStream(realSavePath + "\\" + saveFilename);
                        /**創建一個緩衝區*/
                        byte buffer[] = new byte[1024];
                       /**判斷輸入流中的數據是否已經讀完的標識*/
                        int len = 0;
                       /** 循環將輸入流讀入到緩衝區當中,(len=in.read(buffer))>0就表示in裏面還有數據*/
                        while((len=in.read(buffer))>0){
                      /**使用FileOutputStream輸出流將緩衝區的數據寫入到指定的目錄(savePath + "\\" + filename)當中*/
                            out.write(buffer, 0, len);
                        }
                        
                        in.close();
                        
                        out.close();
             
                    }
                }
            }catch (Exception e) {
        e.printStackTrace();
    }

    return "**路徑**";

}

 /**防止文件覆蓋的現象發生,要爲上傳文件產生一個唯一的文件名*/
private String makeFileName(String fileExtName){  
Calendar c = Calendar.getInstance(); 
SimpleDateFormat   df1   =   new   SimpleDateFormat( "yyyy-MM-dd HH:mm:ss");
String CurDatetime = df1.format(c.getTime());
String DOCID = CurDatetime + String.valueOf(Math.random()).substring(2, 4);
DOCID = DOCID.replace(":", "").replace(" ", "").replace("-", "");
return DOCID+"."+fileExtName;
   }
   




/**
    * 爲防止一個目錄下面出現太多文件,要使用hash算法打散存儲
   */ 
   private String makePath(String filename,String savePath){
       /**得到文件名的hashCode的值,得到的就是filename這個字符串對象在內存中的地址*/      
    int hashcode = filename.hashCode();
       int dir1 = hashcode&0xf;  //0--15
       int dir2 = (hashcode&0xf0)>>4;  //0-15
       /**構造新的保存目錄*/
       String dir = savePath + "\\" + dir1 + "\\" + dir2;  //upload\2\3  upload\3\5      
       File file = new File(dir);
       /**如果目錄不存在*/
       if(!file.exists()){
           file.mkdirs();
       }
       return dir;
}

以上就是上傳文件的主要邏輯代碼,樓樓是是以Spring+Springmvc+Mybatis爲框架進行搭建的項目工程。所以裏面有一些

屬於框架的東西。

2.下載文件邏輯

下面是下載的邏輯代碼:

/**下載附件*/
@RequestMapping("/DownFile")
public String  DownFile(HttpServletRequest request,HttpServletResponse response,String upautor)
throws ServletException, IOException{
/**得到要下載的文件*/
       String fileName = request.getParameter("upautor");  
       String realpath=request.getParameter("realpath");
       String filetype =request.getParameter("filetype");
       fileName = new String(fileName.getBytes("iso8859-1"),"UTF-8");
       String picgif="gif";
       String picjpg="jpg";
       String picpng="png";        
       String picbmp="bmp"; 
       String redrect=null;
       /**圖片的格式有(具體分析):   
        * gig  tif rgb dib eps jpe pcx 
       得到要下載的文件*/
       File file = new File(realpath + "\\" + fileName);
      /**處理文件名*/
       String realname = fileName.substring(fileName.indexOf("_")+1);
      /**設置響應頭,控制瀏覽器下載該文件*/
       /**判斷附件格式,如果爲圖片則顯示,否則下載*/
       if(filetype.equals(picgif)||filetype.equals(picjpg)||filetype.equals(picpng)||filetype.equals(picbmp)){   
        response.setContentType(filetype);
        response.setContentLength((int)file.length());
        response.setHeader("Content-Disposition", "inline; filename="
        + URLEncoder.encode(realname, "UTF-8"));
        InputStream in = new FileInputStream(file);
        OutputStream out = response.getOutputStream();
        long statistic = 0;
    byte buffer[] = new byte[8192];
    do {
    int bytesRead = in.read(buffer);
    if (bytesRead == -1)
    break;
    out.write(buffer, 0, bytesRead);
    statistic = statistic + bytesRead;
    out.flush();
    } while (true);
    in.close();
    out.close();
       
        redrect="redirect:/upload/showFile";
       }else
       {
        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(realname, "UTF-8"));
        /**讀取要下載的文件,保存到文件輸入流*/
       FileInputStream in = new FileInputStream(realpath + "\\" + fileName);
       /**創建輸出流*/
       OutputStream out = response.getOutputStream();
       /**創建緩衝區*/
       byte[] buffer = new byte[1024];
       int len = 0;
       /**循環將輸入流中的內容讀取到緩衝區當中*/
       while((len=in.read(buffer))>0){
        response.setContentType("image/jpg");
       response.setContentLength(buffer.length);
          /**輸出緩衝區的內容到瀏覽器,實現文件下載*/
           out.write(buffer, 0, len);
       }
       
       in.close();
       out.close();
       }
       return "**路徑**";
}

通過以上可以在web工程中實現文件的上傳和下載,項目中是以圖片爲例,併爲其設置了格式的限制,修改對應需要自適應。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章