package com.renchao; import org.junit.Test; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.file.StandardOpenOption; import java.util.List; import java.util.zip.CRC32; import java.util.zip.CheckedInputStream; import java.util.zip.Deflater; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ZipDemo { public static void main(String[] args) throws Exception { // 创建一个ZipOutputStream类的对象 ZipOutputStream out = new ZipOutputStream(new FileOutputStream("C:\\Users\\RENCHAO\\Desktop\\新建文件夹\\output.zip")); // 创建一个File对象,表示要压缩的文件夹 File file = new File("C:\\Users\\RENCHAO\\Desktop\\aa"); // 调用compress方法,将file对象压缩到out对象中 compress(out, file, ""); // 关闭out对象 out.close(); } public static void compress(ZipOutputStream out, File file, String base) throws Exception { if (file.isDirectory()) { // 如果file对象是一个目录,则获取该目录下的所有文件和目录 File[] files = file.listFiles(); // 如果files数组不为空,则遍历files数组中的所有元素 if (files != null && files.length > 0) { for (File f : files) { // 递归调用compress方法,将f对象压缩到out对象中 compress(out, f, base + file.getName() + "/"); } } } else { // 如果file对象是一个文件,则创建一个ZipEntry对象,表示该文件在压缩包中的路径和名称 ZipEntry entry = new ZipEntry(base + file.getName()); // 将entry对象添加到out对象中 out.putNextEntry(entry); // 创建一个FileInputStream类的对象 FileInputStream in = new FileInputStream(file); // 创建一个byte数组 byte[] buffer = new byte[1024]; int len; // 读取in对象中的数据到buffer数组中,直到读取完毕 while ((len = in.read(buffer)) > 0) { // 将buffer数组中的数据写入到out对象中 out.write(buffer, 0, len); } // 关闭in对象 in.close(); } } @Test public void test01() throws IOException { // ArrayList list = new ArrayList<>(); // collect(new File("C:\\Users\\RENCHAO\\Desktop\\temp-sss\\aa\\20240314094355A076"), list); long l = System.currentTimeMillis(); File file = new File("C:\\Users\\RENCHAO\\Desktop\\aa.pdf"); try (/*FileInputStream in = new FileInputStream(file);*/ ZipOutputStream out = new ZipOutputStream(new FileOutputStream("C:\\Users\\RENCHAO\\Desktop\\temp-sss\\aa\\output.zip"))) { ZipEntry entry = new ZipEntry("aa.pdf"); entry.setMethod(ZipEntry.STORED); // Set the size of the file entry.setSize(file.length()); // Set the CRC-32 checksum of the file entry.setCrc(calcChecksum(file)); out.setLevel(Deflater.NO_COMPRESSION); out.putNextEntry(entry); System.out.println("创建entry:" + (System.currentTimeMillis() - l)); l = System.currentTimeMillis(); // byte[] buffer = new byte[2048]; // int len; // while ((len = in.read(buffer)) > 0) { // out.write(buffer, 0, len); // } try (FileChannel fileChannel = FileChannel.open(file.toPath(), StandardOpenOption.READ)) { ByteBuffer buffer = ByteBuffer.allocate(8192); // 8KB缓冲区 int bytesRead; while ((bytesRead = fileChannel.read(buffer)) != -1) { buffer.flip(); // 切换到读模式 out.write(buffer.array(), 0, bytesRead); buffer.clear(); // 清空缓冲区 } } //ZipOutputStream.write可以使用NIO操作吗,以提高效率 System.out.println("压缩完成:" + (System.currentTimeMillis() - l)); } } public void collect(File file, List list) { if (file.isDirectory()) { File[] files = file.listFiles(); if (files != null && files.length > 0) { for (File f : files) { collect(f, list); } } } else { list.add(file); } } // Calculate CRC-32 checksum of a file private static long calcChecksum(File file) throws IOException { try (FileInputStream fis = new FileInputStream(file); CheckedInputStream cis = new CheckedInputStream(fis, new CRC32())) { byte[] buffer = new byte[2048]; while (cis.read(buffer) >= 0) { // Reading the file to calculate CRC-32 checksum } return cis.getChecksum().getValue(); } } private static long calcChecksum2(File file) throws IOException { try (FileChannel fileChannel = FileChannel.open(file.toPath(), StandardOpenOption.READ)) { ByteBuffer buffer = ByteBuffer.allocate(1024); CRC32 crc32 = new CRC32(); while (fileChannel.read(buffer) != -1) { buffer.flip(); crc32.update(buffer); buffer.clear(); } return crc32.getValue(); } } }