本文共 8045 字,大约阅读时间需要 26 分钟。
package com.willhonor.test;import static java.nio.charset.StandardCharsets.UTF_8;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.nio.charset.Charset;import java.util.Enumeration;import java.util.zip.ZipEntry;import java.util.zip.ZipFile;import java.util.zip.ZipOutputStream;import org.junit.Test;/** * 有两处可能需要指定编码 * 1. zipEntry 的名称和 comment 的编码可以单独指定 * 2. zipEntry 的内容编码,该部分只需编码与解码方案一致即可,可以使用任意编码, * 即 如果写入数据时,使用 utf-8 编码,则读取数据时也使用 utf-8 解码即可。 * @author jokee * */public class Test_1 { /** 1. 生成 zip 文件 * a. 先指定 zipEntry 的名称,然后为其写入数据,这里的数据部分以字节数组的形式提供, * 所以可以采用任意编码,当然在提取该 zipEntry 的数据内容时,也必须采用一致的解码方案。 */ @Test public void test_generateZipFile() throws Exception { String zipFile = "E:\\temp\\temp\\docs.zip"; // create new zip file File file = new File(zipFile); if (file.exists()) { file.delete(); } file.createNewFile(); // zipEntry 名称和 comment 使用 utf-8 编码 ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(file), UTF_8);// zipOutputStream.setComment("这是文档文件,压缩包"); zipOutputStream.setComment("this is zip file, just for test."); // 1 first file,zipEntry 内容数据使用 utf-8 编码 byte[] f1 = "hello this world, I'm here now, so happy!".getBytes(UTF_8); addEntry(zipOutputStream, "hello.txt", f1); // 2 second file byte[] f2 = "这是我最喜欢的 blog 网站了
".getBytes(UTF_8); addEntry(zipOutputStream, "我的书签收藏.html", f2); // 4 empty directory addEntry(zipOutputStream, "others\\", null); addEntry(zipOutputStream, "其它\\", null); addEntry(zipOutputStream, "com\\", null); addEntry(zipOutputStream, "com\\will\\", null); addEntry(zipOutputStream, "com\\will\\honor\\", null); // 3 third file byte[] f3 = "/** this is java source */".getBytes(UTF_8); addEntry(zipOutputStream, "com/will/honor/test.java", f3); // close zipOutputStream.close(); } private void addEntry(ZipOutputStream os, String entityName, byte[] bytes) { try { ZipEntry entry = new ZipEntry(entityName); os.putNextEntry(entry); if (bytes != null && bytes.length > 0) { os.write(bytes); } os.closeEntry(); } catch (IOException e) { e.printStackTrace(); } } /** 读取/打印压缩文件内容,这里使用文本文件作为实验。通常 zip 文件中会包含例如 pdf/png 等格式的文件,不适合打印 */ @Test public void test_useZipFileClass() throws Exception { String fileName = "E:\\temp\\temp\\docs.zip"; // String fileName = "E:\\temp\\temp\\usediffcharset.zip"; // zipEntry 名称和 commend 使用 utf-8 解码 ZipFile zipFile = new ZipFile(new File(fileName), UTF_8); Enumeration entries = zipFile.entries(); while(entries.hasMoreElements()) { ZipEntry en = entries.nextElement(); System.out.println(String.format("[%s]", new Object[] { en.getName()})); if (!en.isDirectory()) { InputStream is = zipFile.getInputStream(en); byte[] bytes = getAllBytes(is); // zipEntry 内容使用 utf-8 解码 System.out.println(new String(bytes, UTF_8) + "\n---------------"); } } zipFile.close(); } public byte[] getAllBytes(InputStream is) { if (is != null) { ByteArrayOutputStream out = new ByteArrayOutputStream(); int bufSize = 1024; byte[] buf = new byte[bufSize]; int res = 0; try { while((res = is.read(buf)) > 0) { out.write(buf, 0, res); } } catch (IOException e) { e.printStackTrace(); } return out.toByteArray(); } return null; } /** * zipEntry 的名称使用 UTF-8 编码,而其数据内容使用 gbk 编码 */ @Test public void test_useDifferentCharset() throws Exception { String fileName = "E:\\temp\\temp\\usediffcharset.zip"; File file = new File(fileName); if (file.exists()) { file.delete(); } file.createNewFile(); ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(file), UTF_8); // add 1 // zipEntry 名称使用 utf-8 编码 zipOutputStream.putNextEntry(new ZipEntry("Java编程实战.txt")); // zipEntry 内容使用 gbk 编码 zipOutputStream.write("这是Java编程实战,这是注释".getBytes(Charset.forName("gbk"))); // zipOutputStream.close(); }}
package com.willhonor.test;import static java.nio.charset.StandardCharsets.UTF_8;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.nio.file.FileSystems;import java.nio.file.FileVisitResult;import java.nio.file.Files;import java.nio.file.LinkOption;import java.nio.file.Path;import java.nio.file.Paths;import java.nio.file.SimpleFileVisitor;import java.nio.file.attribute.BasicFileAttributes;import java.util.zip.ZipEntry;import java.util.zip.ZipOutputStream;import org.junit.Test;/** * 压缩指定的目录 或 文件 * @author jokee * */public class Test_2 { public static final String FILE_SYSTEM_SEPARATOR = FileSystems.getDefault().getSeparator(); public static void main(String[] args) { String path = "E:\\360Downloads\\Software"; String zipFileName = "E:\\360Downloads\\"; doZip(path, zipFileName); } /** * * @param filePath 需要被压缩的目录或文件 * @param zipFileName 生成的压缩文件,如果为 null ,则生成的压缩文件处于 filePath 路径同级 */ public static void doZip(String filePath, String zipFileName) { if (filePath != null) { Path path = Paths.get(filePath, new String[] { }); if (Files.notExists(path, new LinkOption[] { LinkOption.NOFOLLOW_LINKS})) { System.out.println("指定路径不存在,path:" + path.toString()); System.out.println("程序退出"); System.exit(1); } Path parentPath = path.getParent(); final int parentPathLen = parentPath.toString().length(); zipFileName = getZipFileName(path, zipFileName); File zipFile = createZipFileIfNotExist(zipFileName); try { final ZipOutputStream os = new ZipOutputStream(new FileOutputStream(zipFile), UTF_8); if (Files.isDirectory(path, new LinkOption[] { LinkOption.NOFOLLOW_LINKS})) { // is directory Files.walkFileTree(path, new SimpleFileVisitor() { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { os.putNextEntry(new ZipEntry(dir.toString() .substring(parentPathLen + FILE_SYSTEM_SEPARATOR.length()) + FILE_SYSTEM_SEPARATOR)); os.closeEntry(); return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException { os.putNextEntry(new ZipEntry(path.toString() .substring(parentPathLen + FILE_SYSTEM_SEPARATOR.length()))); os.write(Files.readAllBytes(path)); os.closeEntry(); return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { return FileVisitResult.CONTINUE; } }); }else { // is a file os.putNextEntry(new ZipEntry(path.toString() .substring(parentPathLen + FILE_SYSTEM_SEPARATOR.length()))); os.write(Files.readAllBytes(path)); os.closeEntry(); } os.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } private static String getZipFileName(Path path, String zipFileName) { String fileName = path.getFileName().toString(); if (zipFileName == null) { Path parenPath = path.getParent(); zipFileName = parenPath.toString() + FILE_SYSTEM_SEPARATOR + fileName + ".zip"; } else { if (zipFileName.endsWith(FILE_SYSTEM_SEPARATOR)) { // zipFileName 为目录 zipFileName += fileName; } if (!zipFileName.endsWith(".zip")) { zipFileName += ".zip"; } } return zipFileName; } private static File createZipFileIfNotExist(String zipFileName) { File file = new File(zipFileName); if (!file.exists()) { File parentFile = file.getParentFile(); if (parentFile != null && !parentFile.exists()) { parentFile.mkdirs(); } try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } return file; }}
转载地址:http://vjlsi.baihongyu.com/