L'Isola di Niente
L'Isola di Niente » PyGObject Tips » ファイルの圧縮、展開

ファイルの圧縮、展開

GZip, ZIP 形式ファイルの圧縮、展開

GZip ファイル

GZip (*.gz) ファイルは Gio のみで扱えます。
#!/usr/bin/env python3

"""
    GZip 圧縮、展開のサンプル
    ソースファイルを GZip 圧縮し decompress.py で展開
"""

from gi.repository import Gio

def convert(source, dest, converter):
    src_stream = source.read()
    dst_stream = dest.replace(None, False, 0)
    conv_stream = Gio.ConverterOutputStream(base_stream=dst_stream, converter=converter)
    conv_stream.splice(src_stream, 0)

f = Gio.file_new_for_path(__file__)
gz = Gio.file_new_for_path("compress.gz")
de = Gio.file_new_for_path("decompress.py")

# compress
convert(f, gz, Gio.ZlibCompressor(format=Gio.ZlibCompressorFormat.GZIP))
# decompress
convert(gz, de, Gio.ZlibDecompressor(format=Gio.ZlibCompressorFormat.GZIP))

ZIP ファイル

ZIP (*.zip) ファイルは libgsf を使います。
#!/usr/bin/env python3

"""
    Zip 圧縮、展開のサンプル
    ソースファイルを Zip 圧縮
    __ZIPOUT__ ディレクトリを作成し、その中に展開
"""

import os, gi
gi.require_version('Gsf', '1')
from gi.repository import Gsf

SRC_NAME = os.path.basename(__file__)
ZIP_NAME = os.path.splitext(SRC_NAME)[0] + ".zip"
OUT_DIR = "__ZIPOUT__"

#
# 圧縮、 close させないと decompress でファイル認識できないので注意
# 
outf = Gsf.OutputStdio.new(ZIP_NAME)
outzip = Gsf.OutfileZip.new(outf)
child = outzip.new_child(SRC_NAME, False)
# バイナリで読み込む
with open(__file__, "rb") as f:
    data = f.read()
    child.write(data)
    child.close()
outzip.close()
outf.close()

#
# 展開、 コチラは close 不要てかそんな関数は無い
#
inf = Gsf.InputStdio.new(ZIP_NAME)
inzip = Gsf.InfileZip.new(inf)
folder = Gsf.OutfileStdio.new(OUT_DIR)
num = inzip.num_children()
for i in range(num):
    item = inzip.child_by_index(i)
    itemfile = Gsf.StructuredBlob.read(item)
    itemfile.write(folder)

すべてのアーカイブファイル

file-roller 同様にアーカイブ種類毎にコマンドから取得するしか無さそうです。
ぶっちゃけ libarchive ってのがあったりしますけど。

libarchive 0.4.3 : Python Package Index

Fedora には最初から libarchive.so.13 が入っている、Vala なら普通に使えるようだ。
Python, Gjs にはバインドされていないみたい、残念。
Copyright(C) sasakima-nao All rights reserved 2002 --- 2017.