文章目录
前言
Java中我们用ZipInputStream和ZipOutputStream来完成对zip文件的读写,这两个类都间接继承自FilterInputStream,它们本身并不具备读写文件的能力,(部分源代码如下:)
public class ZipInputStream extends InflaterInputStream implements ZipConstants{...} public class InflaterInputStream extends FilterInputStream {...}
因此它们的构造方法允许传入一个真正具备读写功能的字符流对象。如FileInputStream,FileOutputStream的对象,从而完成文件的读写,另外,如果zip文件中如果有中文文件名时,会抛出异常,这时要在构造方法中通过Charset.forName()方法设置一个字符编码,如“gbk”。l
在读zip文件时,首先创建出ZipInputStream对象,zip文件中的每一个文件都是一个ZipEntry对象,我们要通过ZipInputStream的对象调用getNextEntry()方法获取这些对象读到输入流中。然后通过输入流和输出流完成文件的“读”和“写”。相当于是把一个zip文件“解压缩”。
在写zip文件时,首先创建出ZipOutputStream对象,然后要获得普通文件对象,然后调用putNextEntry()方法,把普通文件“变成”一个个ZipEntry对象后,放入输出流中。然后通过输出流完成文件的“写”。
代码
import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.Charset; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; public class Demo { public static void main(String[] args) { //创建出要解压缩的压缩包的文件对象 File zipFile = new File("C:\\Users\\admin\\Desktop\\新建文件夹 (2)\\AAA.zip"); String zipFileName = zipFile.getName(); String targetDirName = zipFileName.substring(0, zipFileName.indexOf(".")); //创建出目标文件夹 File targetDir = new File(zipFile.getParent() + "\\" + targetDirName); if (!targetDir.exists()) { targetDir.mkdir(); } //构造方法传入FIleInputStream对象,并设置字符编码 try (ZipInputStream in = new ZipInputStream(new FileInputStream(zipFile), Charset.forName("gbk"))) { ZipEntry zipEntry = null; while ((zipEntry = in.getNextEntry()) != null) {//获取压缩包中的文件对象 //拿到每个文件对象的文件名 String zipEntryFileName = zipEntry.getName(); //拿到要写到的目标文件名,即解压缩后的文件名 String zipFilePath = targetDir.getPath() + "//" + zipEntryFileName; //创建出输出流 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(zipFilePath)); byte[] buff = new byte[1024]; int len = -1; //开始边读边写 while ((len = in.read(buff)) != -1) { bos.write(buff, 0, len); } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
上述代码完成了zip文件的读,即相当于“解压缩包”。
public class Demo1 { public static void main(String[] args) { try { //设置原始文件路径 File rootDir = new File("C:\\Users\\admin\\Desktop\\新建文件夹 (2)\\新建文件夹"); //创建ZipOutputStream对象 ZipOutputStream out = new ZipOutputStream(new FileOutputStream(rootDir.getParent()+"\\"+rootDir.getName()+".zip")); File[] files = rootDir.listFiles(); for(File f: files) { //根据文件对象f创建出ZipENtry对象,然后将其放入输出流中。 out.putNextEntry(new ZipEntry(f.getName())); //将文件写入zip文件中 out.write(Files.readAllBytes(f.toPath())); out.closeEntry(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
上述代码完成了把多个文件写入zip文件,相当于是将多个文件“打成”一个压缩包。
总结
zip文件中的每个文件相当于是一个ZipEntry对象,在读文件时,要先通过getNextEntry()将该对象读入到输入流中。然后再完成文件的读。在把文件写入到zip文件时。同样要先创建出ZipEntry对象。把它放入输出流中,然后完成zip文件的写。
zip文件的文件名如果有中文的话,要在ZipOutputStream的构造方法中通过Charset.forName()方法设置字符编码。