1. Introdução básica
A manipulação de arquivos compactados também é um ponto técnico frequentemente usado. Por exemplo, ao exportar vários arquivos para o navegador para download, é necessário adicionar vários arquivos ao arquivo compactado. Por um lado, vários arquivos podem ser baixados de uma só vez tempo. Por outro lado, também pode reduzir o tamanho do arquivo baixado. No entanto, os arquivos de compactação de operação integrados do JDK fornecem apenas o formato zip (o formato rar é protegido por direitos autorais e o formato 7z não deveria ter nascido na versão inicial do JDK), o que é relativamente insípido. , experimentei usar Java para descompactar. Os documentos estão mais ou menos envolvidos em alguns dos trabalhos posteriores, mas não são abrangentes o suficiente, profundos o suficiente e não são profissionais o suficiente. No segundo semestre do ano passado, houve uma demanda por descompactando arquivos em lotes. A implementação de código aberto de compactação e descompactação relacionada a Java foi praticada e é desenvolvida em torno da aplicação diária do trabalho. Os formatos comuns de arquivo compactado são: zip, 7z, rar, portanto, a resposta oferece uma variedade de implementações desses formatos. Este artigo primeiro usa a expansão de formato zip de compactação e descompactação integrada do JDK, detalhada abaixo.
2. Implementação de compactação
2.1 Ferramentas de compressão
package cn.chendd.compress;
import org.apache.commons.lang3.StringUtils;
import java.io.*;
/**
* JDK中内置的zip压缩和解压缩实现
*
* @author chendd
* @date 2023/3/4 19:50
*/
public class CompressZip {
/**
* 压缩文件或文件夹(递归压缩子层)
* @param file 文件或文件夹
* @param zipFile zip文件
* @throws IOException 异常处理
*/
public static void zip(File file, File zipFile) throws IOException {
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile) , Charset.forName("GBK"))) {
generareZipFile(file, zos, file);
}
}
/**
* 压缩文件或文件夹(递归压缩子层)
* @param file 文件或文件夹
* @param zipFile zip文件
* @param charset 编码
* @param comment 备注
* @throws IOException 异常处理
*/
public static void zip(File file, File zipFile , String charset , String comment) throws IOException {
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile) , Charset.forName(charset))) {
if (StringUtils.isNotEmpty(comment)) {
zos.setComment(comment);
}
generareZipFile(file, zos, file);
}
}
/**
* 生成zip文件
* @param inFile 原文件
* @param zos 压缩流
* @param rootFile 根文件
* @throws IOException 异常处理
*/
private static void generareZipFile(File inFile, ZipOutputStream zos, File rootFile) throws IOException {
if (inFile.isFile()) {
putEntryFile(zos, rootFile, inFile);
return;
}
File[] files = inFile.listFiles();
if (files == null || files.length == 0) {
putEntryEmptyFolder(zos , inFile , rootFile);
return;
}
for (File file : files) {
if (file.isDirectory()) {
generareZipFile(file, zos, rootFile);
} else {
putEntryFile(zos, file, rootFile);
}
}
}
/**
* 压缩空文件夹
* @param zos 文件流
* @param file 文件
* @param rootFile 根文件
* @throws IOException 异常处理
*/
private static void putEntryEmptyFolder(ZipOutputStream zos, File file, File rootFile) throws IOException {
String path = StringUtils.substringAfter(file.getAbsolutePath(), rootFile.getAbsolutePath() + File.separator);
ZipEntry zipEntry;
//处理空文件夹
String folder = file.isDirectory() ? "/" : StringUtils.EMPTY;
if (StringUtils.isBlank(path)) {
zipEntry = new ZipEntry(file.getName() + folder);
} else {
zipEntry = new ZipEntry(path + folder);
}
zos.putNextEntry(zipEntry);
zos.closeEntry();
zos.flush();
}
/**
* 压缩文件
* @param zos 文件流
* @param file 文件
* @param rootFile 根文件
* @throws IOException 异常处理
*/
private static void putEntryFile(ZipOutputStream zos, File file, File rootFile) throws IOException {
String path = StringUtils.substringAfter(file.getAbsolutePath(), rootFile.getAbsolutePath() + File.separator);
ZipEntry zipEntry;
if (StringUtils.isBlank(path)) {
zipEntry = new ZipEntry(file.getName());
} else {
zipEntry = new ZipEntry(path);
}
zos.putNextEntry(zipEntry);
Files.copy(file.toPath(), zos);
zos.closeEntry();
zos.flush();
}
}
2.2 Teste de ferramentas de compressão
package cn.chendd.compress;
import org.junit.*;
import java.io.*;
/**
* 测试压缩zip
*
* @author chendd
* @date 2023/3/4 20:44
*/
@RunWith(JUnit4.class)
public class CompressZipTest {
/**
* 测试压缩文件
*/
@Test
public void zipFile() throws IOException {
File projectHome = new File(System.getProperty("user.dir")).getParentFile();
File file = new File(projectHome , "源文件/哈喽.txt");
File zipFile = new File(projectHome , "压缩文件夹/哈喽.zip");
CompressZip.zip(file , zipFile);
System.out.println("压缩源文件:" + file.getAbsolutePath());
System.out.println("压缩后文件:" + zipFile.getAbsolutePath());
}
/**
* 测试压缩文件夹
*/
@Test
public void zipFolder() throws IOException {
File projectHome = new File(System.getProperty("user.dir")).getParentFile();
File folder = new File(projectHome , "源文件/简单文件夹");
File zipFile = new File(projectHome , "压缩文件夹/简单文件夹.zip");
CompressZip.zip(folder , zipFile);
System.out.println("压缩源文件:" + folder.getAbsolutePath());
System.out.println("压缩后文件:" + zipFile.getAbsolutePath());
}
/**
* 测试压缩复杂结构文件夹
*/
@Test
public void zipComplexFolder() throws IOException {
File projectHome = new File(System.getProperty("user.dir")).getParentFile();
File folder = new File(projectHome , "源文件/复杂文件夹");
File zipFile = new File(projectHome , "压缩文件夹/复杂文件夹.zip");
CompressZip.zip(folder , zipFile);
System.out.println("压缩源文件:" + folder.getAbsolutePath());
System.out.println("压缩后文件:" + zipFile.getAbsolutePath());
}
}
3. Execute o exemplo
(compressão de arquivo único)
(compressão de pasta)
(Compressão de estrutura de arquivo complexa)
4. Instruções de implementação
(1) Este artigo usa a API de zip integrada do Java para obter compactação de arquivo (pasta);
(2) Este site escreveu uma vez a implementação da descompactação de arquivos (pastas) usando a API de zip integrada do Java, mas é muito, muito cedo. Você pode verificar isso na pesquisa de texto completo "Java Unzip Folder" neste site. Vamos dar uma olhada., afinal, foi escrito há muito tempo;
(3) Este artigo se concentra principalmente em arquivos compactados (pastas), oferece suporte à compactação de arquivos e pastas individuais, oferece suporte a vários arquivos em uma pasta, incluindo pastas vazias e arquivos vazios e oferece suporte à compactação recursiva de várias pastas ao mesmo tempo;
(4) Suporte "Notas" para arquivos compactados e suporte a arquivos compactados (pastas) contendo nomes chineses;
(5) Endereço de download do código-fonte do projeto: " https://gitee.com/88911006/chendd-examples/tree/master/compress ", consulte o módulo jdk para obter detalhes;
[Para mais implementações profissionais de compactação e descompactação Java, consulte os seguintes artigos]
Compactação e descompactação Java (1) operação de zip integrada do JDK
Compactação e descompactação Java (2) prática Zip4j