/**
* 利用zip库压缩/解压文件夹
* 因为java的基本zip库是不支持中文文件名的。所以压缩后中文名的条目都变成了乱码,利用rar解压工具解压不了名字为乱码的压缩文件,但自己写的解压方法在windows下解压后编码正常显示中文,而其他系统下则不能正常还原;
* 可以用ant.jar包下的zip类来压缩文件夹,apache tools下的zip库是支持中文的。(ant.jar包下面可以下载)
第一种是没处理中文乱码的···
* @author 小苗
*/
第一种:
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; /** * 压缩一个目录,包括目录下的所有文件 * java的基本zip库是不支持中文文件名的。 * 可以用ant.jar包下的zip类,apache tools下的zip库是支持中文的。 * @author 小苗 */ public class CompressDir { /** * 压缩文件夹方法(此方法压缩后有根目录且名字与被压缩文件夹名一样,效果如图1) * @param inputFile 被压缩的文件夹 * @param str 压缩条目根目录名 * @param zipFile 压缩后的输出流 * @throws IOException */ public void comDir2(File inputFile,String str,ZipOutputStream zipFile) throws IOException{ //判断文件是否为文件夹 if(inputFile.isDirectory()){ File[] files = inputFile.listFiles(); zipFile.putNextEntry(new ZipEntry(str+"/")); //使用指定名字创建压缩条目 str = str.length()==0 ? "":str+"/"; for (int i=0;i<files.length;i++) { comDir2(files[i],str+files[i].getName(), zipFile); //递归调用压缩方法 } }else{ InputStream in = new FileInputStream(inputFile); //开始写入新的 ZIP 文件条目并将流定位到条目数据的开始处。 ZipEntry zipname = new ZipEntry(str); zipFile.putNextEntry(zipname); byte[] buff = new byte[1024]; int len = 0; while((len = in.read(buff))!=-1){ zipFile.write(buff, 0, len); } in.close(); } } /** * @param s3 被压缩的文件夹 * @param s4 压缩后输出路径 * @throws IOException */ public void comDir(File s3,File s4) throws IOException { System.out.println("正在压缩文件···"); //定义 Zip格式的输出流 ZipOutputStream zip_out = new ZipOutputStream(new FileOutputStream(s4)); comDir2(s3,s3.getName(),zip_out); //调用压缩方法 zip_out.close(); //关闭流 } /** * 解压缩zip文件的方法 * @param zipFileName 要被解压的文件 * @param outputDirectory 解压输出路径 */ public void unzip(String zipFileName, String outputDirectory) { System.out.println("正在解压···"); try { ZipInputStream in = new ZipInputStream(new FileInputStream(zipFileName)); /*获取ZipInputStream中的ZipEntry条目,一个zip文件中可能包含多个ZipEntry, *当getNextEntry方法的返回值为null,则代表ZipInputStream中没有下一个ZipEntry, *输入流读取完成; */ ZipEntry z = in.getNextEntry(); while (z != null) { System.out.println("unziping " + z.getName()); //创建以zip包文件名为目录名的根目录 File f = new File(outputDirectory); f.mkdirs(); if (z.isDirectory()) { String name = z.getName(); name = name.substring(0, name.length() - 1); f = new File(outputDirectory + File.separator + name); f.mkdirs(); } else { f = new File(outputDirectory + File.separator + z.getName()); f.createNewFile(); FileOutputStream out = new FileOutputStream(f); byte[] buff = new byte[1024]; int len ; while ((len = in.read(buff)) != -1) { out.write(buff,0,len); } out.close(); } z = in.getNextEntry(); //读取下一个ZipEntry } in.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws IOException { CompressDir com = new CompressDir(); //压缩 com.comDir(new File("d:\\Temp"), new File("d:\\temp.zip")); System.out.println("压缩完成!"); //解压 如果此处不指定解压的具体目录,如:test2,那么则直接解压到根目录下 com.unzip("d:\\temp.zip", "d:\\"); System.out.println("解压完成!"); } }
第二种:
问题:①怎么解决中文名文件压缩后为乱码
* java的基本zip库是不支持中文文件名的。参考了网上的一些解决方法
* 发现Ant的apache tools下的zip库是支持中文的。
* 下面就是采用该方式实现的在中文文件名下的文件压缩代码:
在给出实现代码之前,有一点需要指出,那就是必须要在工程中引Ant.jar的包,此包下面可以下载。
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipOutputStream ; /** * @author 小苗 */ //此方法压缩后 没有根目录,效果如图2 public class CompressDir02 { public static File inpath = new File("d:\\Temp"); public static ZipOutputStream zout = null; //输出流确定 static { try { zout = new ZipOutputStream(new FileOutputStream("d:\\temp.zip")); // zout.setEncoding("GBK"); } catch (FileNotFoundException e) { e.printStackTrace(); } } public void dozip(File file) { File[] files = file.listFiles(); for (File f : files) { if (f.isFile()) { docopy(f); } else dozip(f); } } public void docopy(File f) { try { InputStream in = new FileInputStream(f); //创建压缩条目 String tempPath = f.getAbsolutePath().replace( inpath.getAbsolutePath() + "\\", ""); ZipEntry zent = new ZipEntry(tempPath); System.out.println("压缩条目:"+tempPath); zout.putNextEntry(zent); byte[] buff = new byte[1024]; int len = 0; while ((len = in.read(buff)) != -1) { zout.write(buff, 0, len); } in.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws IOException { CompressDir02 com = new CompressDir02(); File ff = new File("d:\\Temp"); System.out.println("开始压缩文件···"); com.dozip(ff); System.out.println("压缩完成!"); com.zout.close(); } }
图1: