1. 程式人生 > >Java批量檔案打包下載

Java批量檔案打包下載

經常遇到選擇多個檔案進行批量下載的情況,可以先將選擇的所有的檔案生成一個zip檔案,然後再下載,該zip檔案,即可實現批量下載,但是在打包過程中,常常也會出現下載過來的zip檔案中裡面有亂碼的檔名,通過使用ant.jar中的org.apache.tools.zip裡的ZipOutPutStream為實現編碼的設定。 
程式碼如下: 

ant包引用 

Xml程式碼  
<dependency>  
  <groupId>ant</groupId>  
  <artifactId>ant</artifactId>  
  <version>1.6.5</version>  
</dependency>  

壓縮下載的action程式碼 
package demo.action;  
  
import java.io.BufferedInputStream;  
import java.io.BufferedOutputStream;  
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.net.URLEncoder;  
  
import javax.servlet.http.HttpServletResponse;  
  
import org.apache.log4j.Logger;  
import org.apache.struts2.ServletActionContext;  
import org.apache.tools.zip.ZipEntry;  
import org.apache.tools.zip.ZipOutputStream;  
  
import com.opensymphony.xwork2.ActionSupport;  
  
/** 
 * 批量下載檔案: 
 *   使用ant.jar包中的org.apache.tools.zip.*完成壓縮, 
 * java原生也有java.util.zip.*但是測試了下無法搞定壓縮 
 * 檔案內檔名的中文問題   
 * @author yangcong 
 *  
 */  
public class BatchDownloadAction extends ActionSupport {  
  
    private Logger Log = Logger.getLogger(BatchDownloadAction.class);  
    private static final String FilePath = "D:\\";  
  
    private static final long serialVersionUID = -8694640030455344419L;  
  
    public String execute() {  
        //生成的ZIP檔名為Demo.zip  
        String tmpFileName = "Demo.zip";  
        byte[] buffer = new byte[1024];  
        String strZipPath = FilePath + tmpFileName;  
        try {  
            ZipOutputStream out = new ZipOutputStream(new FileOutputStream(  
                    strZipPath));  
            // 需要同時下載的兩個檔案result.txt ,source.txt  
            File[] file1 = { new File(FilePath+"test1.txt"),  
                    new File(FilePath+"測試2.docx") };  
            for (int i = 0; i < file1.length; i++) {  
                FileInputStream fis = new FileInputStream(file1[i]);  
                out.putNextEntry(new ZipEntry(file1[i].getName()));  
                //設定壓縮檔案內的字元編碼,不然會變成亂碼  
                out.setEncoding("GBK");  
                int len;  
                // 讀入需要下載的檔案的內容,打包到zip檔案  
                while ((len = fis.read(buffer)) > 0) {  
                    out.write(buffer, 0, len);  
                }  
                out.closeEntry();  
                fis.close();  
            }  
            out.close();  
            this.downFile(getResponse(), tmpFileName);  
        } catch (Exception e) {  
            Log.error("檔案下載出錯", e);  
        }  
        return null;  
    }  
  
    /** 
     * 獲取Response 
     * @return 
     */  
    private HttpServletResponse getResponse() {  
        return ServletActionContext.getResponse();  
    }  
  
    /** 
     * 檔案下載 
     * @param response 
     * @param str 
     */  
    private void downFile(HttpServletResponse response, String str) {  
        try {  
            String path = FilePath + str;  
            File file = new File(path);  
            if (file.exists()) {  
                InputStream ins = new FileInputStream(path);  
                BufferedInputStream bins = new BufferedInputStream(ins);// 放到緩衝流裡面  
                OutputStream outs = response.getOutputStream();// 獲取檔案輸出IO流  
                BufferedOutputStream bouts = new BufferedOutputStream(outs);  
                response.setContentType("application/x-download");// 設定response內容的型別  
                response.setHeader(  
                        "Content-disposition",  
                        "attachment;filename="  
                                + URLEncoder.encode(str, "UTF-8"));// 設定頭部資訊  
                int bytesRead = 0;  
                byte[] buffer = new byte[8192];  
                // 開始向網路傳輸檔案流  
                while ((bytesRead = bins.read(buffer, 0, 8192)) != -1) {  
                    bouts.write(buffer, 0, bytesRead);  
                }  
                bouts.flush();// 這裡一定要呼叫flush()方法  
                ins.close();  
                bins.close();  
                outs.close();  
                bouts.close();  
            } else {  
                response.sendRedirect("../error.jsp");  
            }  
        } catch (IOException e) {  
            Log.error("檔案下載出錯", e);  
        }  
    }  
}  

  經過在windows環境下測試通過,使用struts2