(java)多个附件打包成压缩文件(*.ZIP)以及打包时常见的文件乱码和文件名乱码以及丢失文件或文件损坏问题解决办法

2/22/2017来源:ASP.NET技巧人气:1031

java打包有两种方式,一种是使用JDK自带的类(java.util.zip.ZipOutputStream;java.util.zip.ZipEntry)。 还有一种是使用apache提供的类(org.apache.tools.zip.ZipOutputStream;org.apache.tools.zip.ZipEntry)。 常见错误解决办法: 压缩包内的文件乱码解决办法:JDK自带的压缩类不提供设置编码的方法,这样会导致压缩包里面的文件名乱码,所以在使用的时候要注意引用apache提供的包调用 setEncoding("GBK")  方法。 压缩包的某些文件损坏解决办法:一定要及时的清空和关闭 (zos.flush();zos.close();),否则会导致压缩包的某些文件损坏。 丢失中文文件名解决办法: fileName = new String(fileName.getBytes(),"ISO-8859-1"); // 中文转码 还有一种情况,就是下载下来的压缩包内缺少文件,明明打包了3个文件,下载下来却只有2个或者1个,那是因为常用的压缩软件WinRAR会自动过滤掉0kb 的文件,可以使用360压缩打开,即可看到被WinRAR过滤掉的0kb文件。 完整代码:
package com.atwp.dowonzip;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DowonZipServlet extends HttpServlet {

	PRivate static final long serialVersionUID = -5575023666592266887L;

	public DowonZipServlet() {
		super();
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		String fileName = "文件打包.zip";
		fileName = new String(fileName.getBytes(), "ISO-8859-1"); // 必须转码,否则会丢失中文文件名。
		
		response.setContentType("application/OCTET-STREAM");
		response.setHeader("Content-Disposition", "attachment; filename=" + fileName); // 设置文件名
		ZipOutputStream zos = new ZipOutputStream(response.getOutputStream()); 
		
		/* 把需要打包的文件存入数组 */
		File[] files = new File[3];
		files[0] = new File("F:/OwO/testFiles/imgs/1.jpg");
		files[1] = new File("F:/OwO/testFiles/imgs/2.jpg");
		files[2] = new File("F:/OwO/testFiles/imgs/3.jpg");
		
		try {
			byte[] zipFile = zipFile(files, "", zos);
			response.getOutputStream().write(zipFile); // 输出到页面
		} 
		catch (Exception e) {
			e.printStackTrace();
		}
		finally {  // 必须释放以及关闭,否则可能会出现压缩的文件出现损坏。
			zos.flush();
			zos.close();
		}

	}

	private byte[] zipFile(File[] subs, String baseName, ZipOutputStream zos) throws IOException {
		
		try {
			byte[] buffer = null;
			for (int i = 0; i < subs.length; i++) {
				File f = subs[i];
				zos.putNextEntry(new ZipEntry(baseName + f.getName()));
				FileInputStream fis = new FileInputStream(f);
				buffer = new byte[1024];
				int r = 0;
				while ((r = fis.read(buffer)) != -1) zos.write(buffer, 0, r);
				fis.close();
			}
			return buffer;
		} 
		catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		finally {     // 必须释放以及关闭,否则可能会出现压缩的文件出现损坏。
			zos.flush();
			zos.close();
		}
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doGet(request, response);
	}
}