Java生成zip包并下载

通过流在内存中直接生成zip,或者字符串生成zip

1.根据已有的文件或者字符串,生成Zip输出流,从浏览器下载zip包
jar包ant-1.6.5.jar
指定文件打包,或者指定字符串压缩成指定文件,并下载
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
/**
* 类说明:压缩指定文件,到指定目录/文件
*/
public class ZipUtil extends HttpServlet {
     private static final long serialVersionUID = 1L;
     
     @Override
    protected void doGet(HttpServletRequest request,   HttpServletResponse response) throws ServletException,  IOException  {
           String zipFileName = "下载文件名称.zip";
           response.reset();
        response.setHeader("Pragma", "public");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/zip;   charset=utf-8");
         response.addHeader("Content-Disposition","attachment;fileName="+new String(zipFileName.getBytes("GBK"),"ISO-8859-1"));
        
        File file = new File("E:/test.dat");
        try {
            downloadZip(file,  response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public void downloadZip(File srcFile, HttpServletResponse  response)  throws Exception{
          OutputStream out = null;
          InputStream in = null;
          ZipOutputStream zipOut = null;
          try {
               out = response.getOutputStream();
               zipOut = new ZipOutputStream(out);
               zipOut.setEncoding("GBK");
               createZipWithFile(srcFile, zipOut, "aa/1.txt");
               String content = "<?xml version=\"1.0\"  encoding=\"gb2312\"?><Head><name>wangjj</name><age>23</age></Head>";
               createZipWithStr(content, zipOut, "aa/11/1.xml");
          }catch (Exception e) {
               if(zipOut != null)
                    IOUtils.closeQuietly(zipOut);
               out.close();
          }finally {           
               if(zipOut != null)
                    IOUtils.closeQuietly(zipOut);
               out.close();
          }
    }
    
    private int BUFFER_SIZE = 2 * 1024;
    
    /**
     * 把指定的文件打包到zip中,并指定文件目录
     * @param sourceFile
     * @param zos
     * @param path:可随意设置目录,比如:aa\测试.txt
     * @throws Exception
     */
    public void createZipWithFile(File sourceFile,  ZipOutputStream zos, String path) throws Exception{
      byte[] buf = new byte[BUFFER_SIZE];
      if(sourceFile.isFile()) {
           zos.putNextEntry(new ZipEntry(path));
           int len;
           FileInputStream in = new FileInputStream(sourceFile);
           while((len = in.read(buf)) != -1) {
                zos.write(buf, 0, len);
           }
           zos.closeEntry();
           in.close();
      }
    }
    
    /**
     * 把字符串打包到zip中,并指定文件目录
     * @param content:要打包的字符串
     * @param zos:压缩包输出流
     * @param pathName:字符串保存成什么目录下的什么文件,比如:aa\测试.txt
     * @throws Exception
     */
    public void createZipWithStr(String content, ZipOutputStream  zos, String pathName) throws Exception{
      byte[] buf = new byte[BUFFER_SIZE];
      zos.putNextEntry(new ZipEntry(pathName));
      InputStream in = new  ByteArrayInputStream(content.getBytes());
      int len;
      while((len = in.read(buf)) != -1) {
           zos.write(buf, 0, len);
      }
      zos.closeEntry();
      in.close();
    }
2.指定目录,打包该目录下的所有文件和文件夹,并下载。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* 类说明:下载指定目录
*/
public class ZipUtil3 extends HttpServlet {
    private static final Logger log = LoggerFactory.getLogger(ZipUtil3.class);


    protected void doGet(HttpServletRequest request,  HttpServletResponse response) throws ServletException, IOException  {
        String zipFileName = "下载文件名称.zip";
        response.reset();
        response.setHeader("Pragma", "public");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/zip;  charset=utf-8");
        response.addHeader("Content-Disposition","attachment;fileName="+new String(zipFileName.getBytes("GBK"),"ISO-8859-1"));
        
        try {
            downloadZip("E:\\aa",response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public static void downloadZip(String sourcePath, HttpServletResponse response) {
        OutputStream out = null;
        ZipOutputStream zos = null;
        try {
            out = response.getOutputStream();
            zos = new ZipOutputStream(out);
            zos.setEncoding("gbk");//此处修改字节码方式,可以解决文件名中文乱码。  
            File file = new File(sourcePath);
            compress(file, zos, file.getName());
        } catch (FileNotFoundException e) {  
            log.error("创建ZIP文件失败",e);  
        }catch (Exception e) {  
            log.error("创建ZIP文件失败",e);  
        }finally {  
            try {  
                if (zos != null) {  
                    zos.close();  
                }  
            } catch (IOException e) {  
                log.error("创建ZIP文件失败",e);  
            }  
        }  
    }
    
    private static final int BUFFER_SIZE = 2 * 1024;
    
    private static String temp = "";
    
    public static void compress(File sourceFile, ZipOutputStream zos, String name) throws Exception{
        //打包的zip包有根目录,可以在这里去掉根目录,只打包目录下的文件和文件夹
        if(temp != "") {
            if(name.contains(temp) && name.length() > temp.length()) {
                name = name.substring(temp.length()+1);
            }
        }else {
            temp = name;
        }
        byte[] buf = new byte[BUFFER_SIZE];
        if(sourceFile.isFile()) {
            zos.putNextEntry(new ZipEntry(name));
            int len;
            FileInputStream in = new FileInputStream(sourceFile);
            while((len = in.read(buf)) != -1) {
                zos.write(buf,0,len);
            }
            zos.closeEntry();
            in.close();
        }else {
            File[] listFiles = sourceFile.listFiles();
            if(listFiles == null || listFiles.length == 0) {
                if(name != temp) {
                    zos.putNextEntry(new ZipEntry(name+"/"));                    
                }
                zos.closeEntry();
            }else {
                for(File file : listFiles) {
                    //递归打包,如果不拼接name则zip包中只会有文件,不会有目录结构
                    compress(file, zos, name+"/"+file.getName());
                    file.delete();//打包之后删除源文件
                }
            }
        }
        
    }
}
注意1: 如果压缩后zip包中文件名称中文乱码,可以使用apache下的包
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
同时压缩流设置编码方式GBK,(因为服务器在Windows上,所以我设置的编码为GBK)
注意2:以上的方式是通过浏览器下载。通过 response.getOutputStream(); 获取到输出流,如果我们想要把压缩流保存到硬盘上可以使用以下方式:
FileOutputStream fos = new FileOutputStream("E:测试.zip"); 
ZipOutputStream zos = new ZipOutputStream(fos);

版权声明:本文为T_P_F原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。