java对 zip文件的压缩和解压(ant解决中文乱码)
Posted 倾舞绕梦
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java对 zip文件的压缩和解压(ant解决中文乱码)相关的知识,希望对你有一定的参考价值。
说明:
1、对于压缩的文件,当文件名称是中文时,若使用JDK API中自带的类(java.util.zip.ZipEntry; java.util.zip.ZipOutputStream;)进行压缩,压缩完成后,可以看到压缩包中的文件名称是乱码(文件的内容无乱码),所以使用ANT中的ant.jar中的类(org.apache.tools.zip.ZipEntry; org.apache.tools.zip.ZipOutputStream;)用来解决此问题;
2、解压缩时,如果压缩包中为空,则创建空文件夹
import 如下:
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.util.Enumeration; import org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipFile; import org.apache.tools.zip.ZipOutputStream;
一、压缩文件(ZIP):
/** *@name 获取File对象 *@description 相关说明 *@param path 文件路径 *@return File *@throws IOException *@author LJCH *@history 修订历史(历次修订内容、修订人、修订时间等) */ public static File getFile(String path) throws IOException { // 创建文件对象 File file = null; if (path != null && !path.equals("")) { file = new File(path); } if (!file.exists()) { file.createNewFile(); } // 返回文件 return file; } /** *@name 压缩文件 *@description 相关说明 *@param srcFilePath 源文件 *@param destZipFile 目标文件 *@return file 压缩文件的FILE对象 *@throws IOException *@author LJCH *@history 修订历史(历次修订内容、修订人、修订时间等) */ public static File getZipFile(String srcFilePath, String destZipFile) throws IOException { return getZipFile(new File(srcFilePath),destZipFile); } /** *@name 获取压缩文件的File *@description 相关说明 *@param srcFile 源文件 *@param destZipFile 目标文件 *@return file 压缩文件的FILE对象 *@throws IOException *@author LJCH *@history 修订历史(历次修订内容、修订人、修订时间等) */ public static File getZipFile(File srcFile, String destZipFile) throws IOException { final File zipFile = getFile(destZipFile); // 文件输出流 final FileOutputStream outputStream =new FileOutputStream(zipFile); // 压缩流 final ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream); if (srcFile.isDirectory()) { directory(zipOutputStream, srcFile); } else { zipFile(srcFile, zipOutputStream); } // 关闭压缩流、文件流 zipOutputStream.close(); outputStream.close(); return zipFile; } /** *@name 递归压缩目录结构 *@description 相关说明 *@param zipOutputStream 压缩文件流 *@param file file *@throws IOException *@author LJCH *@history 修订历史(历次修订内容、修订人、修订时间等) */ public static void directory(ZipOutputStream zipOutputStream, File file) throws IOException { final File[] files = file.listFiles(); for (File fileTemp : files) { if (fileTemp.isDirectory()) { directory(zipOutputStream, fileTemp); } else { zipFile(fileTemp, zipOutputStream); } } if (files.length == 0) { try { zipOutputStream.putNextEntry(new ZipEntry(getPath(file) + File.separator)); } catch (Exception e) { e.printStackTrace(); } } } /** *@name 获得该文件在压缩包中的相对路径 *@description 相关说明 *@param file File *@return String *@author LJCH *@history 修订历史(历次修订内容、修订人、修订时间等) */ public static String getPath(File file) { final String str1 = file.getAbsolutePath(); final int n1 = str1.length(); final String str2 = file.getAbsolutePath(); final int n2 = str2.length(); final String str3 = file.getName(); final int n3 = str3.length(); final String str = str2.substring(n1 - n3, n2); return str; } /** * 将文件数据写入文件压缩流 * @param file 带压缩文件 * @param zipOutputStream 压缩文件流 * @throws IOException */ private static void zipFile(File file, ZipOutputStream zipOutputStream) throws IOException { if (file.exists()) { if (file.isFile()) { final FileInputStream fis = new FileInputStream(file); final BufferedInputStream bis = new BufferedInputStream(fis); final ZipEntry entry = new ZipEntry(file.getName()); zipOutputStream.putNextEntry(entry); final int MAX_BYTE = 10 * 1024 * 1024; // 最大流为10MB long streamTotal = 0; // 接收流的容量 int streamNum = 0; // 需要分开的流数目 int leaveByte = 0; // 文件剩下的字符数 byte[] buffer; // byte数据接受文件的数据 streamTotal = bis.available(); // 获取流的最大字符数 streamNum = (int) Math.floor(streamTotal / MAX_BYTE); leaveByte = (int) (streamTotal % MAX_BYTE); if (streamNum > 0) { for (int i = 0; i < streamNum; i++) { buffer = new byte[MAX_BYTE]; bis.read(buffer, 0, MAX_BYTE); zipOutputStream.write(buffer, 0, MAX_BYTE); } } // 写入剩下的流数据 buffer = new byte[leaveByte]; bis.read(buffer, 0, leaveByte); // 读入流 zipOutputStream.write(buffer, 0, leaveByte); // 写入流 zipOutputStream.closeEntry(); // 关闭当前的zip entry // 关闭输入流 bis.close(); fis.close(); } } }
二、解压缩文件(ZIP)
/** *@name 解压zip格式压缩包 *@description 相关说明 *@param sourceZip 源文件 *@param destDir 目标文件地址 *@throws Exception *@author LJCH *@history 修订历史(历次修订内容、修订人、修订时间等) */ @SuppressWarnings("unchecked") private static void unzip(String sourceZip, String destDir) throws Exception { ZipFile zipFile = null; try { final File f = new File(sourceZip); if ((!f.exists()) && (f.length() <= 0)) { throw new RuntimeException("要解压的文件不存在!"); } //一定要加上编码,之前解压另外一个文件,没有加上编码导致不能解压 zipFile = new ZipFile(f, "gbk"); String gbkPath; String strtemp; final Enumeration<ZipEntry> e = zipFile.getEntries(); if (!e.hasMoreElements()) { final File dir = new File(destDir + File.separator + f.getName().substring(0, f.getName().lastIndexOf("."))); if (!dir.exists()) { dir.mkdirs(); } return; } while (e.hasMoreElements()) { final org.apache.tools.zip.ZipEntry zipEnt = e.nextElement(); gbkPath = zipEnt.getName(); strtemp = destDir + File.separator + gbkPath; if (zipEnt.isDirectory()) { //目录 final File dir = new File(strtemp); if (!dir.exists()) { dir.mkdirs(); } continue; } else if (zipEnt.getName().substring(zipEnt.getName().length() - 1, zipEnt.getName().length()).equals(File.separator)) { final File dir = new File(strtemp); if (!dir.exists()) { dir.mkdirs(); } continue; } else { // 读写文件 final InputStream is = zipFile.getInputStream(zipEnt); final BufferedInputStream bis = new BufferedInputStream(is); // 建目录 final String strsubdir = gbkPath; for (int i = 0; i < strsubdir.length(); i++) { if (strsubdir.substring(i, i + 1).equalsIgnoreCase("/")) { final String temp = destDir + File.separator + strsubdir.substring(0, i); final File subdir = new File(temp); if (!subdir.exists()) { subdir.mkdir(); } } } final FileOutputStream fos = new FileOutputStream(strtemp); final BufferedOutputStream bos = new BufferedOutputStream(fos); int len; final byte[] buff = new byte[1024]; while ((len = bis.read(buff)) != -1) { bos.write(buff, 0, len); } bos.close(); fos.close(); } } } catch (Exception e) { //logger.error("解压文件出现异常:", e); throw e; }finally{ zipFile.close(); } } /** *@name 解压文件用于后期扩展RAR等其他压缩格式 *@description 相关说明 *@param sourceFile 源文件 *@param destDir 目标路径 *@throws Exception *@author LJCH *@history 修订历史(历次修订内容、修订人、修订时间等) */ private static void unfile(String sourceFile, String destDir) throws Exception { // 根据类型,进行相应的解压缩 final String type = sourceFile.substring(sourceFile.lastIndexOf(".") + 1); final File dir = new File(destDir); if(!dir.exists()){ dir.mkdirs(); } if (type.toLowerCase().equals("zip")) { unzip(sourceFile, destDir); } else { throw new RuntimeException("只支持zip格式的压缩包!"+type); } } /** *@name 解压到指定目录 *@description 相关说明 *@param sourceFile 源文件 *@param destDir 目标目录 *@throws Exception *@author LJCH *@history 修订历史(历次修订内容、修订人、修订时间等) */ public static void deCompress(String sourceFile, String destDir) throws Exception { if (sourceFile == null || destDir == null) { throw new RuntimeException("目录不能为空"); } // 保证文件夹路径最后是"/"或者"" final char lastChar = destDir.charAt(destDir.length() - 1); if (lastChar != ‘/‘ && lastChar != ‘\‘) { unfile(sourceFile, destDir+File.separator); }else{ unfile(sourceFile, destDir); } } /** *@name 解压到指定目录 *@description 相关说明 *@param sourceFile 源文件 *@param destDir 目标路径 *@throws Exception *@author LJCH *@history 修订历史(历次修订内容、修订人、修订时间等) */ public static void deCompress(File sourceFile, String destDir) throws Exception { if (!sourceFile.exists() || sourceFile.isDirectory()) { throw new RuntimeException("文件不存在"); } deCompress(sourceFile.getPath(), destDir); } /** *@name 解压到当前目录 *@description 相关说明 *@param sourceFile 源文件 *@throws Exception *@author LJCH *@history 修订历史(历次修订内容、修订人、修订时间等) */ public static void deCompress(String sourceFile) throws Exception { // 获得文件目录 int i = sourceFile.lastIndexOf("/"); final int d = sourceFile.lastIndexOf("\"); if (i == -1 && d == -1) { throw new RuntimeException("目录separator异常"); } else if (i == -1) { i = d; } final String destDir = sourceFile.substring(0, i + 1); unfile(sourceFile, destDir); } /** *@name 解压到当前目录 *@description 相关说明 *@param sourceFile 源文件 *@throws Exception *@author LJCH *@history 修订历史(历次修订内容、修订人、修订时间等) */ public static void deCompress(File sourceFile) throws Exception { if (!sourceFile.exists() || sourceFile.isDirectory()) { throw new RuntimeException("文件不存在"); } deCompress(sourceFile.getPath()); }
文中如有存在描述不正确,欢迎指正、补充!!!
以上是关于java对 zip文件的压缩和解压(ant解决中文乱码)的主要内容,如果未能解决你的问题,请参考以下文章
Java能否对压缩文件进行操作,例如:对zip,rar,tar等文件进行复制。