如何将一个文件夹压缩成多个 .zip 文件,并且所有文件都可以独立提取?

如何将一个文件夹压缩成多个 .zip 文件,并且所有文件都可以独立提取?

我处理一些包含数百万张图像的大型图像数据集,并且我经常需要压缩每个处理步骤的结果以将其上传作为备份。

我发现有些数据集可以作为一组 .zip 文件下载,这些文件可以单独解压到同一个文件夹中,作为一个一致的数据集。这非常方便,因为它使我能够流水线式地执行下载 -> 解压 -> 删除存档的过程,这在时间和存储空间方面都更高效,如下文以任意时间/大小解释的那样:

  • 解压一个 100GB 的 .zip 文件时,假设下载需要 5 分钟,解压需要 10 分钟。我需要15分钟获取我的所有数据。假设 .zip 的压缩率为 50%,我需要使用 100+200 =300GB磁盘空间。
  • 解压两个 50GB 的 .zip 文件时,假设下载每个文件需要 2.5 分钟,解压每个文件需要 5 分钟。我可以这样做:花 2.5 分钟下载 zip1,花 5 分钟解压 zip1,同时花 2.5 分钟下载 zip2,删除 zip1,然后在 5 分钟内解压 zip2,总共 2.5+5+5 =12.5 分钟。同时,我只需要在磁盘上同时最多有 zip2、folder1 和 folder2,所以 50+100+100 =250GB磁盘空间。

随着我们增加单独的 zip 文件数量,这些时间和空间节省也会增加。因此,我正在寻找一种方法来做到这一点。

我的要求如下:

  • 该方法适用于任何文件夹结构,无论其深度如何
  • 压缩结果为 .zip 文件大致相等大小
  • 所有生成的档案都可以单独解压以重建部分文件夹(有时我可能只想使用部分数据集进行测试,在这种情况下我不想解压整个数据集)
  • 选修的:
    • 该方法应该能够显示进度条
    • 该方法快速、有效

我想我可以编写一个满足前几个要求的 bash 或 python 脚本,但我怀疑它是否足够快。

我知道 zip 中的 -s 开关和 7z 中的 -v 开关,但它们都要求用户拥有档案的所有部分才能够解压其中的任何部分,这是不太理想的。

答案1

我有一个脚本可以协助完成这项任务。下面是一个 Bash 脚本示例,它将文件单独压缩为不同的 ZIP 存档,使它们可以单独提取。您可以在包含文件的目录中执行此脚本以生成 ZIP 存档。我已经测试了这个过程,Python(尤其是使用 Pandas)可以轻松读取这些存档而无需手动提取。

#!/bin/bash

# Set the target directory
target_directory="/path/to/your/directory"

# Navigate to the target directory
cd "$target_directory" || exit

# Iterate through files in the directory
for file in *.csv; do
  if [ -f "$file" ]; then
    # Build the target ZIP file name
    zip_file="${file}.zip"

    # Check if the target ZIP file already exists, if yes, skip compression
    if [ -f "$zip_file" ]; then
      echo "File $zip_file already exists. Skipping compression."
    else
      # Compress the file
      zip "$zip_file" "$file"
      if [ $? -eq 0 ]; then
        echo "File $file compressed successfully into $zip_file."
        # Remove the original CSV file after successful compression
        rm "$file"
      else
        echo "File $file compression failed."
      fi
    fi
  fi
done

在目录中运行此脚本将为每个 CSV 文件创建单独的 ZIP 文件,并在压缩成功后删除原始 CSV 文件。

答案2

ZIP 文件格式实际上只是一个包含压缩文件的容器(基本上是一个文件夹)。这与 Linux 平台上经常使用的 .tar.gz 格式形成对比。ZIP 的优点是可以按照您希望的方式单独提取内容,而无需提取整个档案。

事实上,包括 Windows 在内的大多数操作系统都支持打开 ZIP 文件夹来查看文件名和元数据,而无需提取整个档案。提取大型目录结构的一个子集并不困难(在 Windows 中,您只需复制粘贴选定的文件即可)
7-Zip也可以做到这一点,但您必须按“复制”按钮,然后指定目的地。

嵌套 .zip 文件存在问题,通常必须完全提取父 .zip 文件才能检查子 .zip 文件。

顺便提一下,我提到的 .tar.gz 格式使用与 ZIP 相同的 DEFLATE 算法,但有时压缩效果更好,因为文件名和元数据也被压缩了。这样做的代价是通常必须提取整个档案才能查看其内容。

相关内容