无法解压缩使用zipfile构建的归档文件(Python)

Cat*_*Cat 4 python zip archive zipfile

我在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()
Run Code Online (Sandbox Code Playgroud)

这是例外:

zipfile.BadZipfile:目录“ env \ index”和标头“ env / index”中的文件名不同。

更新:我cStringIO.StringIO()用一个临时文件(tempfile.mkstemp("temp.zip"))替换了字符串缓冲区,现在可以使用了。当zipfile模块写入破坏归档文件的缓冲区时,会发生某些事情,但不确定是什么问题。

问题是我正在以“ r” /“ w”模式而不是“ rb” /“ wb”模式打开的文件读取/写入信息。在Linux中这不是问题,但是由于字符编码,这在Windows中给了我错误。解决了。

jed*_*rds 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")
Run Code Online (Sandbox Code Playgroud)

产生以下输出:

C:\destination\path
C:\path\to\folder
C:\destination\path
C:\path o
         older
Run Code Online (Sandbox Code Playgroud)

请注意,\ t和\ f 在最后一行解释为tabformfeed

有趣的是,您也可以将反斜杠更改为正斜杠(即open("C:/path/to/folder"),这将起作用。

或者,使用...反斜杠(即open("C:\\path\\to\\folder"))来转义反斜杠。

IMO,最简单明了的解决方案是简单地添加r


编辑:看起来您需要使用第二个解决方案,正斜杠。zipfile库显然是严格的-鉴于这是一个仅窗口的错误,它可能会漏掉。(请参阅问题6839)。


Cat*_*Cat 4

在这里找到我的问题的答案:http://www.penzilla.net/tutorials/python/scripting

我粘贴了与压缩目录相关的两个函数。问题不在于字符串缓冲区,也不在于斜杠,而在于我迭代和写入 zip 文件的方式。这两个递归函数解决了这个问题。使用 迭代整个子目录树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!"
Run Code Online (Sandbox Code Playgroud)