不解压压缩包的情况下,遍历压缩包中所有的文件夹和文件

本文介绍了一个Java工具类,用于检查用户上传的.zip、.tar或.tar.gz格式压缩包内是否包含特定的文件夹(如model/)和文件(如dockerfile、inference_services.py和model_data_import.py)。该类利用ApacheCommonsCompress库进行文件检查。

需求是:想要校验用户上传的压缩包中是否包含指定的文件夹和文件。

工具类目前支持:.zip  .tar   .tar.gz形式的压缩包文件

工具类如下:

pom中引入如下依赖:

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-compress</artifactId>
            <version>1.21</version> <!-- 根据需要选择合适的版本 -->
        </dependency>
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Set;

/**
 * 用于检查镜像文件压缩包是否包含要求的文件夹,以及文件名
 */
public class CompressionChecker {

    //此处,修改为自己需要检验的文件夹名称或者问价名称。
    private static final String MODEL_FOLDER_NAME = "model/";
    private static final String DOCKERFILE_NAME = "dockerfile";
    private static final String INFERENCE_SERVICE_PY_NAME = "inference_services.py";
    private static final String MODEL_DATA_IMPORT_PY_NAME = "model_data_import.py";

    public static boolean checkCompression(String filePath) throws IOException {
        File file = new File(filePath);
        String fileName = file.getName().toLowerCase();

        if (fileName.endsWith(".zip")) {
            return checkZipFile(file);
        } else if (fileName.endsWith(".tar") || fileName.endsWith(".tar.gz")) {
            return checkTarFile(file);
        }

        // Unsupported file type
        return false;
    }

    private static boolean checkZipFile(File file) throws IOException {
        try (InputStream inputStream = new FileInputStream(file);
             ArchiveInputStream archiveInputStream = new ArchiveStreamFactory().createArchiveInputStream(ArchiveStreamFactory.ZIP, inputStream)) {

            Set<String> entries = new HashSet<>();
            ZipArchiveEntry entry;
            while ((entry = (ZipArchiveEntry) archiveInputStream.getNextEntry()) != null) {
                processEntry(entry, archiveInputStream, entries);
            }

            return entries.contains(MODEL_FOLDER_NAME) && entries.contains(DOCKERFILE_NAME) &&
                    entries.contains(INFERENCE_SERVICE_PY_NAME) && entries.contains(MODEL_DATA_IMPORT_PY_NAME);
        } catch (ArchiveException e) {
            throw new RuntimeException(e);
        }
    }

    private static boolean checkTarFile(File file) throws IOException {
        try (InputStream inputStream = new FileInputStream(file)) {
            Set<String> entries = new HashSet<>();

            ArchiveInputStream tarInput;
            if (file.getName().endsWith(".gz")) {
                tarInput = new TarArchiveInputStream(new org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream(inputStream));
            } else {
                tarInput = new TarArchiveInputStream(inputStream);
            }

            ArchiveEntry entry;
            while ((entry = tarInput.getNextEntry()) != null) {
                if (entry instanceof TarArchiveEntry) {
                    processEntry((TarArchiveEntry) entry, tarInput, entries);
                }
            }

            return entries.contains(MODEL_FOLDER_NAME) && entries.contains(DOCKERFILE_NAME) &&
                    entries.contains(INFERENCE_SERVICE_PY_NAME) && entries.contains(MODEL_DATA_IMPORT_PY_NAME);
        }
    }

    private static void processEntry(ZipArchiveEntry entry, ArchiveInputStream archiveInputStream, Set<String> entries) throws IOException {
        if (entry.isDirectory()) {
            String folderName = new File(entry.getName()).getName().toLowerCase();
            entries.add(folderName+"/");
            // 递归处理文件夹内部的内容
            ArchiveEntry subEntry;
            while ((subEntry = archiveInputStream.getNextEntry()) != null) {
                if (subEntry.getName().startsWith(entry.getName())) {
                    processEntry((ZipArchiveEntry) subEntry, archiveInputStream, entries);
                } else {
                    String fileName = new File(subEntry.getName()).getName().toLowerCase();
                    entries.add(fileName);
                    break;
                }
            }
        } else {
            String fileName = new File(entry.getName()).getName().toLowerCase();
            entries.add(fileName);
        }
    }

    private static void processEntry(TarArchiveEntry entry, ArchiveInputStream archiveInputStream, Set<String> entries) throws IOException {
        if (entry.isDirectory()) {
            String folderName = new File(entry.getName()).getName().toLowerCase();
            entries.add(folderName+"/");
            // 递归处理文件夹内部的内容
            ArchiveEntry subEntry;
            while ((subEntry = archiveInputStream.getNextEntry()) != null) {
                if (subEntry.getName().startsWith(entry.getName())) {
                    processEntry((TarArchiveEntry) subEntry, archiveInputStream, entries);
                } else {
                    String fileName = new File(subEntry.getName()).getName().toLowerCase();
                    entries.add(fileName);
                    break;
                }
            }
        } else {
            String fileName = new File(entry.getName()).getName().toLowerCase();
            entries.add(fileName);
        }
    }
}

### Ubuntu 批量解文件夹中所有压缩包 在 Ubuntu 系统中,可以通过多种方式批量解文件夹中的所有压缩包。以下是几种常见的方法: #### 方法一:使用 `find` `xargs` 通过组合 `find` `xargs` 命令来查找并解指定类型的压缩包。 对于 `.zip` 文件: ```bash find /path/to/folder -type f -name "*.zip" -print0 | xargs -0 -I {} unzip {} ``` 对于 `.tar.gz` 或 `.tgz` 文件: ```bash find /path/to/folder -type f \( -name "*.tar.gz" -o -name "*.tgz" \) -print0 | xargs -0 -I {} tar zxvf {} ``` 对于 `.gz` 文件: ```bash find /path/to/folder -type f -name "*.gz" -print0 | xargs -0 -I {} gunzip {} ``` 对于 `.rar` 文件(需先安装 `unrar` 工具[^2]): ```bash sudo apt-get update && sudo apt-get install unrar find /path/to/folder -type f -name "*.rar" -print0 | xargs -0 -I {} unrar x {} ``` 以上命令会递归地遍历目标文件夹 `/path/to/folder` 中的所有压缩包,并逐一解它们[^1]。 --- #### 方法二:使用 `for` 循环 利用 Bash 的 `for` 循环手动处理每种类型的压缩包。 对于 `.zip` 文件: ```bash cd /path/to/folder for file in *.zip; do unzip "$file"; done ``` 对于 `.tar.gz` 或 `.tgz` 文件: ```bash cd /path/to/folder for file in *.tar.gz *.tgz; do tar zxvf "$file"; done ``` 对于 `.gz` 文件: ```bash cd /path/to/folder for file in *.gz; do gunzip "$file"; done ``` 对于 `.rar` 文件: ```bash cd /path/to/folder for file in *.rar; do unrar x "$file"; done ``` 这种方法适用于已知特定路径下的压缩包类型。 --- #### 方法三:Python 脚本实现批量解 如果需要更灵活的方式,可以编写 Python 脚本来完成批量解任务。以下是一个针对 `.zip` 文件的示例脚本[^4]: ```python import zipfile import os def batch_unzip(directory): for root, dirs, files in os.walk(directory): for file in files: if file.endswith(".zip"): zip_file_path = os.path.join(root, file) with zipfile.ZipFile(zip_file_path, 'r') as zf: extract_to = os.path.splitext(zip_file_path)[0] zf.extractall(extract_to) if __name__ == "__main__": target_directory = "/path/to/folder" batch_unzip(target_directory) ``` 运行此脚本后,它会在指定目录及其子目录中寻找所有的 `.zip` 文件,并将其解到对应的同名文件夹中。 --- #### 注意事项 - 如果遇到权限问题,请尝试在命令前加上 `sudo`。 - 对于其他类型的压缩包(如 `.7z`),可能需要额外安装工具(如 `p7zip-full`)。 - 使用 `gunzip` 时需要注意,该命令会直接删除原始 `.gz` 文件;若希望保留原文件,则应改用 `gzip -d -k`[^3]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值