通过流在内存中直接生成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版权协议,转载请附上原文出处链接和本声明。