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