Java文件压缩与解压缩(四)

来源:互联网 发布:linux vi退出编辑模式 编辑:程序博客网 时间:2024/05/21 10:41
package com.cn;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 java.util.zip.ZipEntry;import java.util.zip.ZipFile;import java.util.zip.ZipInputStream;import java.util.zip.ZipOutputStream;//错误小结://1 关于file.isFile()与file.isDirectory()记忆出了偏差.//  错误以为若是Directory一定是file,file不一定是Directory//  更正:file和Directory是两码事.只能是file或Directory中其中一个.//  要看的1 传入一个路径直接压缩了.//2 血的教训://  zip()方法中没有关闭流zos.导致压缩后的文件解压时出错//重要总结://1 关于zip和unzip的核心操作对象是每一个文件!!!//  比如碰到一个directory,那么会去遍历里面的每一个文件,挨个对其进行压缩.//  不要错误地理解,若是一个directory,那么会将其作为一个整体进行压缩.//2 在JAVA中每一个压缩文件都用一个ZipEntry表示//  所以在压缩的过程中要得到每个文件的完整路径(从最外层文件夹至文件本身)//  用此完整路径为每个压缩文件new()一个ZipEntry//3 所以利用zipEntry可记录原来的目录层次.解压后才保持原样//  也可以看到在解压时利用entrys.hasMoreElements()来挨个//  解压每个zipEntrypublic class TestZipAndUnZip {   public static void main(String[] args) throws Exception {   TestZipAndUnZip test=new TestZipAndUnZip();   //将某一个文件压缩成zip//   test.zip("E:\\", "aa\\1.txt", "E:\\cc1.zip");      //将某一个目录压缩成zip   //test.zip("E:\\aa", "bb\\", "E:\\zz.zip");//right//    // test.zip("E:\\", "aa", "E:\\zz678910.zip");//right////   //将某一个zip解压//   test.unZipFile("E:\\zz.zip", "E:\\zzzz");      /////////////////////以下正确///////////////////////////////   //压缩和解压单个文件//   test.zip2("E:\\aa\\1.txt","E:\\aaaaaaa\\aa1234.zip");//   test.unZipFile2("E:\\aaaaaaa\\aa1234.zip", "E:\\aaaaaaa\\aaxixihaha");      //压缩和解压一个目录   test.zip2("D:\\developmentTools","E:\\20.zip");   test.unZipFile2("E:\\20.zip", "E:\\555aaxx99xxx");      /////////////////////以上正确//////////////////////////////   }   /** * @param willZipDirPath    被压缩文件(目录)所在目录 * @param willZipFileName   被压缩文件(目录)的名称 * @param toFilePath        压缩后文件(目录)名 */public void zip(String willZipDirPath, String willZipFileName, String zipedFileName) {System.out.println("…………………以下为zip()方法…………………………");if (willZipDirPath == null) {return;}File willZipDir = new File(willZipDirPath);if (!willZipDir.exists() || !willZipDir.isDirectory()) {return;}// 获得目录绝对路径String willZipDirAbsolutePath = willZipDir.getAbsolutePath();System.out.println("willZipDir.getAbsolutePath()="+willZipDirAbsolutePath);//压缩后的文件File zipedFile = new File(zipedFileName);try {//从压缩后的文件得到压缩输出流ZipOutputStream//这里的zos只指向了压缩后文件的最外层.那么它怎么//维持了原来的目录结构呢?//就是利用了ZipEntry!!!//在fileToZip()方法中就可以看到ZipEntry的使用!!ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipedFile));if (willZipFileName.equals("*")) {//若传入的是*表示将此路径下所有东西都要压缩//所以调用dirToZip()dirToZip(willZipDirAbsolutePath, willZipDir, zos);} else {//将被压缩的文件File willZipFile = new File(willZipDirPath, willZipFileName);System.out.println("ccccccccccc name="+willZipFile.getName());System.out.println("ccccccccccc getAbsolutePath="+willZipFile.getAbsolutePath());if (willZipFile.isFile()) {System.out.println("…………………最外层开始压缩文件………………………");fileToZip(willZipDirPath, willZipFile, zos);System.out.println("…………………最外层压缩文件结束………………………");}if (willZipFile.isDirectory()) {System.out.println("…………………最外层开始压缩目录………………………");dirToZip(willZipDirPath, willZipFile, zos);System.out.println("…………………最外层压缩目录结束………………………");}// 关闭流!!!zos.close();System.out.println("…………………以上为zip()方法…………………………");}} catch (Exception e) {// TODO: handle exception}}   /** * @param dirPath      被压缩文件所在目录 * @param willZipFile  被压缩文件的名称 * @param zos          输出流 */public void fileToZip(String dirPath, File willZipFile,ZipOutputStream zos){   FileInputStream fis=null;   ZipEntry zipEntry=null;   byte [] buffer=new byte[1024*8];   int len=0;   if (willZipFile.isFile()) {try {fis=new FileInputStream(willZipFile);zipEntry=new ZipEntry(getEntryName(dirPath, willZipFile));zos.putNextEntry(zipEntry);System.out.println("…………………以下为fileToZip()方法…………………………");System.out.println("zipEntry.getName="+zipEntry.getName());System.out.println("zipEntry.isDirectory="+zipEntry.isDirectory());System.out.println("zipEntry.getSize="+zipEntry.getSize());System.out.println("zipEntry.getTime="+zipEntry.getTime());System.out.println("zipEntry.getComment="+zipEntry.getComment());System.out.println("…………………以上为fileToZip()方法…………………………");while((len=fis.read(buffer))!=-1){zos.write(buffer, 0, len);}zos.closeEntry();fis.close();} catch (Exception e) {}}  }/** * @param dirPath     被压缩目录所在的上级目录 * @param willZipDir  被压缩目录 * @param zos         输出流 */public void dirToZip(String dirPath, File willZipDir, ZipOutputStream zos) {if (willZipDir.isDirectory()) {File[] files = willZipDir.listFiles();//处理-->该文件夹下无文件            if (files.length==0) {ZipEntry zipEntry=new ZipEntry(getEntryName(dirPath, willZipDir));try {zos.putNextEntry(zipEntry);zos.closeEntry();} catch (Exception e) {e.printStackTrace();}return;}            //处理-->该文件夹下的所有文件            for (int i = 0; i < files.length; i++) {File file = files[i];//若是文件,递归调用fileToZip()if (file.isFile()) {System.out.println("xxxxxxxxxx内层开始fileToZip()方法xxxxxxxxxx");fileToZip(dirPath, file, zos);System.out.println("xxxxxxxxxx内层fileToZip()方法结束xxxxxxxxxx");}//若是文件,递归调用dirToZip()if (file.isDirectory()) {System.out.println("xxxxxxxxxx内层开始dirToZip()方法xxxxxxxxxx");dirToZip(dirPath, file, zos);System.out.println("xxxxxxxxxx内层dirToZip()方法结束xxxxxxxxxx");}}}}   /** * @param dirPath      将被压缩文件所在目录 * @param willZipFile  将被压缩的文件 * @return             *///生成的是每个文件的完整路径(从最外层文件夹至文件本身)//这样生成的zipEntry就记录了原来的目录层次.解压后才保持原样public String getEntryName(String dirPath, File willZipFile) {if (!dirPath.endsWith(File.separator)) {dirPath += File.separator;}String willZipFilePath=willZipFile.getAbsolutePath();if (willZipFile.isDirectory()) {willZipFilePath+="/";}int index=willZipFilePath.indexOf(dirPath);System.out.println("xx返回的 entryName="+ willZipFilePath.substring(index+dirPath.length()));return willZipFilePath.substring(index+dirPath.length());}/** * @param zipedFileName 待解压zip文件 * @param unzipDirPath  文件解压后的最外层文件名 * @throws IOException  */public void unZipFile(String zipedFileName,String unzipDirPath) throws Exception{if (!unzipDirPath.endsWith(File.separator)) {unzipDirPath+=File.separator;}try {ZipFile zipedFile=new ZipFile(zipedFileName);ZipEntry zipEntry=null;String entryName=null;String unzipedFileName=null;Enumeration entrys=zipedFile.entries();byte [] buffer=new byte[1024*8];int len=0;while (entrys.hasMoreElements()) {zipEntry=(ZipEntry) entrys.nextElement();entryName=zipEntry.getName();unzipedFileName=unzipDirPath+entryName;System.out.println("…………………以下为unZipFile()方法…………………………");System.out.println("zipedFileName="+zipedFileName);System.out.println("unzipDirPath="+unzipDirPath);System.out.println("entryName="+entryName);System.out.println("unzipedFileName="+unzipedFileName);System.out.println("…………………以上为unZipFile()方法…………………………");if (zipEntry.isDirectory()) {//没有执行此代码new File(unzipedFileName).mkdirs();} else {//总是执行该代码.因为压缩的时候是对每个文件进行压缩的.                    new File(unzipedFileName).getParentFile().mkdirs();}File unzipedFile=new File(unzipedFileName);FileOutputStream fos=new FileOutputStream(unzipedFile);InputStream is=zipedFile.getInputStream(zipEntry);while ((len=is.read(buffer))!=-1) {fos.write(buffer, 0, len);}fos.close();is.close();}} catch (Exception e) {e.printStackTrace();}}//////////////////////////////////////////////////////////////////////////////////////** * 该方法将一个给定路径的文件压缩 * @param willZipPath 将要压缩的文件的路径 * @param zipedPath   该文件压缩后的路径 */public void zip2(String willZipPath,String zipedPath){try {File willZipedFile=new File(willZipPath);File zipedFile=new File(zipedPath);ZipOutputStream zos=new ZipOutputStream(new FileOutputStream(zipedFile));if (willZipedFile.isFile()) {fileToZip2(willZipPath,willZipedFile, zos);}if (willZipedFile.isDirectory()) {dirToZip2(willZipPath,willZipedFile, zos);}//方法调用完成后关闭流zos.close();} catch (Exception e) {// TODO: handle exception}}/** * @param rawPath      * @param willZipedFile * @param zos */ //test.zip2("E:\\aa\\1.txt","E:\\aaaaaaa\\aa1234.zip");public void fileToZip2(String rawPath,File willZipedFile,ZipOutputStream zos){try {//实例化一个名称为ab.txt的ZipEntry对象File file=new File(rawPath);ZipEntry entry = new ZipEntry(getEntryName2(rawPath, file));//把生成的ZipEntry对象加入到压缩文件中//而之后往压缩文件中写入的内容都会放在这个ZipEntry对象里面zos.putNextEntry(entry);InputStream is = new FileInputStream(rawPath);int len = 0;while ((len = is.read()) != -1){zos.write(len);}is.close();//流关闭错误了!!//zos.close();} catch (Exception e) {}}/** * @param rawPath     原文件所在路径 * @param zipedFile   压缩后的文件 * @param zos */public void dirToZip2(String rawPath,File zipedFile, ZipOutputStream zos) {if (zipedFile.isDirectory()) {File[] files = zipedFile.listFiles();//处理-->该文件夹下无文件//            if (files.length==0) {////ZipEntry zipEntry=new ZipEntry(getEntryName(dirPath, willZipDir));//ZipEntry zipEntry=new ZipEntry("");//try {//zos.putNextEntry(zipEntry);//zos.closeEntry();//} catch (Exception e) {//e.printStackTrace();//}//return;//}            for (int i = 0; i < files.length; i++) {File file = files[i];//若是文件,递归调用fileToZip()if (file.isFile()) {fileToZip2(file.getAbsolutePath(),file, zos);}//若是文件,递归调用dirToZip()if (file.isDirectory()) {dirToZip2(file.getAbsolutePath(),file, zos);}}}}/** * @param rawPath  需要压缩的目录或者文件的完整路径 * @param file     需要压缩的文件 * @return         entryName */public String getEntryName2(String rawPath,File file){//file是rawPath对应的filetry {String rawDir=rawPath.substring(3);int rawDirIndex=file.getAbsolutePath().indexOf(rawDir);String entryName=file.getAbsolutePath().substring(rawDirIndex);return entryName;} catch (Exception e) {}return null;}/** * @param zipedFilePath  原压缩文件的路径 * @param unzipPath      文件解压后的路径 */public void unZipFile2(String zipedFilePath, String unzipPath){try {//解压后的最外层文件夹File unzipFile=new File(unzipPath);if (!unzipFile.exists()) {unzipFile.mkdirs();}File zipedFile = new File(zipedFilePath);File perUnzipedFile = null;// 实例化ZipFile对象 这个很容易错!!!!// ZipFile zipFile = new ZipFile(file) ;ZipInputStream zis = new ZipInputStream(new FileInputStream(zipedFile));FileOutputStream fos = null; ZipEntry entry = null; while ((entry = zis.getNextEntry()) != null) { // 得到一个压缩实体perUnzipedFile = new File(unzipPath+File.separator+entry.getName());if (!perUnzipedFile.getParentFile().exists()) { perUnzipedFile.getParentFile().mkdirs(); // 创建父目录}if (!perUnzipedFile.exists()) { // 判断输出文件是否存在perUnzipedFile.createNewFile(); // 创建文件}// 得到每一个实体的输入流fos = new FileOutputStream(perUnzipedFile); int len = 0;while ((len = zis.read()) != -1) {fos.write(len);}}zis.close(); fos.close(); } catch (Exception e) {// TODO: handle exception}}}

原创粉丝点击