Compactação e descompactação Java (1) operação de zip integrada do JDK

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

Java压缩和解压缩(三)Apache Commons Compress实践

Java压缩和解压缩(四)7-Zip-Jbinding实践

Java压缩和解压缩(五)小总结

Acho que você gosta

Origin blog.csdn.net/haiyangyiba/article/details/129353130
Recomendado
Clasificación