物理の駅 Physics station by 現役研究者

テクノロジーは共有されてこそ栄える

Python: 7zip用に既存の圧縮ファイルを分割する

クラウドストレージやアップローダーには、ファイルサイズに上限があることがある。その際、巨大なファイルを分割することが求められる。

巨大なファイルになりがちなのは圧縮ファイルなので、以下、圧縮ファイルを前提として話を進める。圧縮展開プログラムである7zipでは、zipファイルや7zファイルを、.001 .002などの拡張子(ファイル名の末尾)を使って分割することに対応している。GUIでは書庫をサイズで分割オプションから10gを設定、コマンドラインでは-v10g という引数を使ってファイルを10GBごとに分割できるが、既に作成してしまった圧縮ファイルの分割はできない。

以下の例では、既に作ってしまった巨大な圧縮ファイル large_file.7z を、10GBごとに、large_files ディレクトリに分割する例を示す。一時的にメモリ(RAM)に書き込むため、RAMの空き容量が 10GB以上ない場合はエラーが出て実行できない。エラー処理コードは含まない。

import os

def split_file(input_file, output_directory, split_size):
    index = 1
    written_bytes = 0
    file_size = os.path.getsize(input_file)
    print(file_size,"byte")
    with open(input_file, 'rb') as in_f:
        while True:
            output_file = os.path.join(output_directory, f"{os.path.basename(input_file)}.{index:03d}")
            print(output_file)
            copy_bytes = min(split_size, file_size - written_bytes)
            if copy_bytes==0:return
            with open(output_file, 'wb') as out_f:
                out_f.write(in_f.read(copy_bytes))
                written_bytes += copy_bytes
                index += 1

input_file = "large_file.7z"
output_directory = "split_files"
split_size = 10_000_000_000 # 10GB

split_file(input_file, output_directory, split_size)