web-dev-qa-db-ja.com

Python、メモリに書き込むZipファイル

インメモリzipファイルをファイルに書き込むにはどうすればよいですか?

# Create in memory Zip and add files
zf = zipfile.ZipFile(StringIO.StringIO(), mode='w',compression=zipfile.Zip_DEFLATED)
zf.writestr('file1.txt', "hi")
zf.writestr('file2.txt', "hi")

# Need to write it out
f = file("C:/path/my_Zip.zip", "w")
f.write(zf)  # what to do here? Also tried f.write(zf.read())

f.close()
zf.close()
16
user984003

StringIO.getvalueStringIOのコンテンツを返します:

>>> import StringIO
>>> f = StringIO.StringIO()
>>> f.write('asdf')
>>> f.getvalue()
'asdf'

または、seekを使用してファイルの位置を変更することもできます。

>>> f.read()
''
>>> f.seek(0)
>>> f.read()
'asdf'

次のことを試してください。

mf = StringIO.StringIO()
with zipfile.ZipFile(mf, mode='w', compression=zipfile.Zip_DEFLATED) as zf:
    zf.writestr('file1.txt', "hi")
    zf.writestr('file2.txt', "hi")

with open("C:/path/my_Zip.zip", "wb") as f: # use `wb` mode
    f.write(mf.getvalue())

32
falsetru

Python3に対するfalsetruの回答を変更する

1)_io.StringIO_の代わりに_StringIO.StringIO_を使用します

python3のStringIO

2)_b"abc"_の代わりに_"abc"_を使用する、または

python 3.5:TypeError:ファイルへの書き込み時に 'str'ではなくバイトのようなオブジェクトが必要です

3)バイナリ文字列にエンコードするstr.encode(s, "utf-8")

Python 3? で文字列をバイトに変換する最良の方法

_import zipfile
import io
mf = io.BytesIO()

with zipfile.ZipFile(mf, mode="w",compression=zipfile.Zip_DEFLATED) as zf:

    zf.writestr('file1.txt', b"hi")

    zf.writestr('file2.txt', str.encode("hi"))
    zf.writestr('file3.txt', str.encode("hi",'utf-8'))


with open("a.txt.Zip", "wb") as f: # use `wb` mode
    f.write(mf.getvalue())
_

これはgzipでも機能するはずです: Pythonで文字列をgzip圧縮するにはどうすればよいですか?

10
user3226167
  with ZipFile(read_file, 'r') as zipread:
        with ZipFile(file_write_buffer, 'w', Zip_DEFLATED) as zipwrite:
            for item in zipread.infolist():
                # Copy all ZipInfo attributes for each file since defaults are not preseved
                dest.CRC = item.CRC
                dest.date_time = item.date_time
                dest.create_system = item.create_system
                dest.compress_type = item.compress_type
                dest.external_attr = item.external_attr
                dest.compress_size = item.compress_size
                dest.file_size = item.file_size
                dest.header_offset = item.header_offset

Zipファイルの読み取りが破損していて、シンボリックリンクの欠落やタイムスタンプが間違っている破損したファイルに気付いた場合は、ファイルのプロパティがコピーされていない可能性があります。

上記のコードスニペットは、私が問題を解決した方法です。

1
user2182531