目录

  • 文件压缩 ZipOutputStream
  • 文件解压:ZipInputStream

文件压缩 ZipOutputStream

   用ZipOutputStream来压缩一个文件夹时,要搭配ZipEntry来使用。ZipEntry是用来创建压缩文件的。

  举个例子,向压缩文件中添加一个文件的代码:

//zipOut:压缩文件的路径ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipOut));//zipOutputStream.putNextEntry()====> 向压缩包中添加一个文件//new ZipEntry("text1.txt") ======⇒ zip压缩包中文件都是用ZipEntry对象,//"text1.txt"===》是文件在压缩文件的路径,text1.txt表示在压缩文件的根路径zipOutputStream.putNextEntry(new ZipEntry("text1.txt"));

如下图:

在创建ZipEntry对象时可以指定文件在压缩包的位置:new ZipEntry(“second-dir\second-01.txt”)


在使用ZipOutputStream压缩文件时要注意的地方就是这些,下面给一个压缩文件的代码:

static final intBUFFER_SIZE = 4 << 10;/** * 压缩指定目录下的所有文件 * @param dir 指定压缩目录 * @param destZipName 指定压缩包名字 */public void zip(String dir,String zipPath,String destZipName) throws IOException {File file = new File(dir);/**1.为zip文件创建目录*****/String path = file.getParentFile().getAbsolutePath();if(isNull(destZipName))destZipName = file.getName()+".zip";if(isNull(zipPath)) zipPath = path;String zipOut = zipPath + File.separator + destZipName;File zipOutFile = new File(zipOut);if(!zipOutFile.getParentFile().exists()){zipOutFile.getParentFile().mkdirs();} /**为zip文件创建目录*****/ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipOut));if(!file.isDirectory())zipOutputStream.close();File[] subFiles = file.listFiles();for (File subFile : subFiles) {buildZipDir(zipOutputStream,subFile,null);}zipOutputStream.close();}void buildZipDir(ZipOutputStream zipOut,File file,String baseDir) throws IOException {if(file.isFile()){String zipEntryName = baseDir == null " />.getName() : baseDir+File.separator+file.getName();zipOut.putNextEntry(new ZipEntry(zipEntryName));byte[] buffer = new byte[BUFFER_SIZE];try(InputStream inputStream = new FileInputStream(file)){int len = -1;while((len = inputStream.read(buffer)) != -1){zipOut.write(buffer,0,len);}zipOut.flush();zipOut.closeEntry();}}else{//文件是dir,继续递归找文件File[] subFiles = file.listFiles();if(subFiles.length ==0){//处理空文件夹String zipName = baseDir == null ? file.getName() :baseDir + File.separator+ file.getName() ;zipOut.putNextEntry(new ZipEntry(zipName));zipOut.closeEntry();}else{for (File subFile : subFiles) {String subBaseDir =baseDir == null ? file.getName() :baseDir + File.separator+ file.getName() ;buildZipDir(zipOut,subFile,subBaseDir);}}}}public boolean isNull(String str){return str == null || str.equals("");}

测试:

@Testpublic void testZip() throws IOException { String dir = "D:\\test-zip"; //dir : 要压缩的目录 //D:\\yy\\指定压缩文件的位置 //path-test.zip 指定压缩文件的名字 zip(dir,"D:\\yy\\","path-test.zip");}

文件解压:ZipInputStream

  ZipInputStream读取压缩文件,配合ZipFile使用;通过上面的例子,我们知道压缩包里的是一个个ZipEntry对象,在解压时,可以遍历压缩包获取到ZipEntry对象。每一个ZipEntry对象都是一个文件,使用ZipFile可以获取到每一个ZipEntry对象的文件流;获取到文件流就可以将压缩包的文件读出来了。

public void unZip(String zipPath,String unzipPath) throws IOException {File file = new File(zipPath);ZipFile zipFile = new ZipFile(file);//zip文件ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(file));if(isNull(unzipPath))unzipPath = zipPath.replace(".zip","");ZipEntry nextEntry = null;while( (nextEntry = zipInputStream.getNextEntry()) != null){String name = nextEntry.getName();String fileOutPath = unzipPath + File.separator + name;File fileOut = new File(fileOutPath);if(!fileOut.getParentFile().exists()){fileOut.getParentFile().mkdirs();}if(!fileOut.exists()){fileOut.createNewFile();}OutputStreamoutput = new FileOutputStream(fileOutPath);InputStream inputStream = zipFile.getInputStream(nextEntry);//通过ZipFile获取到ZipEntry的文件流int read = -1;byte[] buffer = new byte[BUFFER_SIZE];while((read = inputStream.read(buffer) ) != -1){output.write(buffer,0, read);}output.flush();output.close();inputStream.close();}zipInputStream.close();zipFile.close();}

测试:

 public void testUnzip() throws IOException {String zip = "D:\\yy\\path-test.zip";unZip(zip,null);}