You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
5.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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<File> 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<File> 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();
}
}
}