Java IO教程 - Java Zip文件
Java对ZIP文件格式有直接支持。通常,我们将使用java.util.zip包中的以下四个类来处理ZIP文件格式:
- ZipEntry
- ZipInputStream
- ZipOutputStream
- ZipFile
ZipEntry对象表示ZIP文件格式的归档文件中的条目。
zip条目可以是压缩的或未压缩的。
ZipEntry类具有设置和获取有关ZIP文件中的条目的信息的方法。
ZipInputStream可以从每个条目的ZIP文件读取数据。
ZipOutputStream可以将数据写入每个条目的ZIP文件。
ZipFile是一个从ZIP文件读取条目的实用程序类。
以下代码显示如何创建ZIP文件
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.zip.Deflater; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream;public class Main {public static void main(String[] args) {String zipFileName = "ziptest.zip";String[] entries = new String[2];entries[0] = "test1.txt";entries[1] = "notes" + File.separator + "test2.txt";zip(zipFileName, entries);}public static void zip(String zipFileName, String[] zipEntries) {try (ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFileName)))) {// Set the compression level to best compressionzos.setLevel(Deflater.BEST_COMPRESSION);for (int i = 0; i < zipEntries.length; i++) {File entryFile = new File(zipEntries[i]);if (!entryFile.exists()) {System.out.println("The entry file " + entryFile.getAbsolutePath()+ " does not exist");System.out.println("Aborted processing.");return;}ZipEntry ze = new ZipEntry(zipEntries[i]);zos.putNextEntry(ze);addEntryContent(zos, zipEntries[i]);zos.closeEntry();}} catch (IOException e) {e.printStackTrace();}}public static void addEntryContent(ZipOutputStream zos, String entryFileName)throws IOException, FileNotFoundException {BufferedInputStream bis = new BufferedInputStream(new FileInputStream(entryFileName));byte[] buffer = new byte[1024];int count = -1;while ((count = bis.read(buffer)) != -1) {zos.write(buffer, 0, count);}bis.close();} }
上面的代码生成以下结果。
读取Zip文件
以下代码显示如何读取ZIP文件的内容。
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream;public class Main {public static void main(String[] args) {String zipFileName = "ziptest.zip";String unzipdirectory = "extracted";unzip(zipFileName, unzipdirectory);}public static void unzip(String zipFileName, String unzipdir) {try (ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(zipFileName)))) {ZipEntry entry = null;while ((entry = zis.getNextEntry()) != null) {// Extract teh entry"s contents extractEntryContent(zis, entry, unzipdir);}} catch (IOException e) {e.printStackTrace();}}public static void extractEntryContent(ZipInputStream zis, ZipEntry entry,String unzipdir) throws IOException, FileNotFoundException {String entryFileName = entry.getName();String entryPath = unzipdir + File.separator + entryFileName;createFile(entryPath);BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(entryPath));byte[] buffer = new byte[1024];int count = -1;while ((count = zis.read(buffer)) != -1) {bos.write(buffer, 0, count);}bos.close();}public static void createFile(String filePath) throws IOException {File file = new File(filePath);File parent = file.getParentFile();if (!parent.exists()) {parent.mkdirs();}file.createNewFile();} }
例2
下面的代码显示了如何使用ZipFile类。
当你只想在ZIP文件中列出条目时,ZipFile类派上用场。
import java.io.InputStream; import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipFile;public class Main {public static void main(String[] args) throws Exception {ZipFile zf = new ZipFile("ziptest.zip");// Get the enumeration for all zip entries and loop through themEnumeration<? extends ZipEntry> e = zf.entries();ZipEntry entry = null;while (e.hasMoreElements()) {entry = e.nextElement();// Get the input stream for the current zip entryInputStream is = zf.getInputStream(entry);/* Read data for the entry using the is object */// Print the name of the entrySystem.out.println(entry.getName());}} }
以下代码使用Stream类和lambda表达式重写上述代码。
import java.io.IOException; import java.io.InputStream; import java.util.stream.Stream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile;public class Main {public static void main(String[] args) throws Exception {ZipFile zf = new ZipFile("ziptest.zip");Stream<? extends ZipEntry> entryStream = zf.stream();entryStream.forEach(entry -> {try {// Get the input stream for the current zip entryInputStream is = zf.getInputStream(entry);System.out.println(entry.getName());} catch (IOException e) {e.printStackTrace();}});} }
GZIPInputStream和GZIPOutputStream类用于与GZIP文件格式配合使用。