4

Pythonでzipfileを使用して構築したアーカイブに問題があります。ディレクトリ内のすべてのファイルを繰り返し処理して、アーカイブに書き込んでいます。後でそれらを抽出しようとすると、パス区切り文字に関連する例外が発生します。

the_path= "C:\\path\\to\\folder"
zipped= cStringIO.StringIO()
zf = zipfile.ZipFile(zipped_cache, "w", zipfile.ZIP_DEFLATED)
for dirname, subdirs, files in os.walk(the_path) :
    for filename in files:
        zf.write(os.path.join(dirname, filename), os.path.join(dirname[1+len(the_path):], filename))
zf.extractall("C:\\destination\\path")
zf.close()
zipped_cache.close()

例外は次のとおりです。

zipfile.BadZipfile:ディレクトリ "env\index"とヘッダー"env/index"のファイル名が異なります。

更新:文字列バッファcStringIO.StringIO()を一時ファイル(tempfile.mkstemp("temp.zip"))に置き換えましたが、動作するようになりました。zipfileモジュールがアーカイブを破壊するバッファに書き込むときに何かが起こりますが、問題が何であるかはわかりません。

問題は、「rb」/「wb」ではなく「r」/「w」モードで開いているファイルとの間で情報の読み取り/書き込みを行っていたことでした。これはLinuxでは問題になりませんが、Windowsでは文字エンコードが原因でエラーが発生しました。解決しました。

4

4 に答える 4

5

文字列の前にrを追加して、それが生の文字列であることを示すことを検討する必要があります。パスのバックスラッシュはエスケープ文字として解釈されます。

次のコード:

#!/bin/env python    
print(r"C:\destination\path")
print(r"C:\path\to\folder")
print("C:\destination\path")
print("C:\path\to\folder")

次の出力を生成します。

C:\destination\path
C:\path\to\folder
C:\destination\path
C:\path o
         older

\tと\fは、最後の行でタブフォームフィードとして解釈されることに注意してください。

興味深いことに、バックスラッシュをフォワードスラッシュ(つまりopen("C:/path/to/folder")に変更することもできます。これは機能します。

または、バックスラッシュを...バックスラッシュ(つまりopen("C:\\path\\to\\folder"))でエスケープします。

IMO、最も明確で簡単な解決策は、単にrを追加することです。


編集:2番目の解決策であるスラッシュを使用する必要があるようです。zipfileライブラリは明らかに厳密なものであり、これがウィンドウのみのバグであることを考えると、おそらく侵入します。(問題6839を参照)。

于 2011-05-19T19:34:48.357 に答える
4

ここで私の質問に対する答えを見つけました:http://www.penzilla.net/tutorials/python/scripting

ディレクトリの圧縮に関連する2つの関数を貼り付けています。問題は文字列バッファでもスラッシュでもありませんでしたが、私が繰り返してzipファイルに書き込んでいた方法でした。これらの2つの再帰関数は、問題を修正します。サブディレクトリのツリー全体をで繰り返すことはos.walk、アーカイブを作成するための良い方法ではありません。

def zippy(path, archive):
    paths = os.listdir(path)
    for p in paths:
        p = os.path.join(path, p) # Make the path relative
        if os.path.isdir(p): # Recursive case
            zippy(p, archive)
        else:
            archive.write(p) # Write the file to the zipfile
    return

def zipit(path, archname):
    # Create a ZipFile Object primed to write
    archive = ZipFile(archname, "w", ZIP_DEFLATED) # "a" to append, "r" to read
    # Recurse or not, depending on what path is
    if os.path.isdir(path):
        zippy(path, archive)
    else:
        archive.write(path)
    archive.close()
    return "Compression of \""+path+"\" was successful!"
于 2011-05-20T23:26:13.840 に答える
1

パスのバックスラッシュをエスケープする必要があります。

以下を変更してみてください。

  • the_path= "C:\path\to\folder"the_path = "C:\\path\\to\\folder"、そして
  • zf.extractall("C:\destination\path")zf.extractall("C:\\destination\\path")
于 2011-05-19T19:35:25.710 に答える
1

Windowsでも、パス区切り文字としてスラッシュを使用できます。zipファイルを作成するときに試してみることをお勧めします。

于 2011-05-19T20:05:03.473 に答える