无法解压使用 zipfile (Python) 构建的存档

发布于 2024-11-08 01:44:25 字数 888 浏览 3 评论 0原文

我在使用 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”不同。

更新:我用临时文件 (tempfile.mkstemp("temp.zip")) 替换了字符串缓冲区 cStringIO.StringIO(),现在它可以工作了。当 zipfile 模块写入缓冲区时会发生一些情况,从而损坏存档,但不确定问题是什么。

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

I'm having problems with an archive that I built using zipfile in Python. I'm iterating over all the files in a directory and writing them to an archive. When I attempt to extract them afterward I get an exception related to the path separator.

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()

Here's the exception:

zipfile.BadZipfile: File name in
directory "env\index" and header
"env/index" differ.

Update: I replaced the string buffer cStringIO.StringIO() with a temporary file (tempfile.mkstemp("temp.zip")) and now it works. There's something that happens when the zipfile module writes to the buffer that corrupts the archive, not sure what the problem is though.

The issue was that I was reading/writing the information from/into files that were open in "r"/"w" mode instead of "rb"/"wb". This isn't an issue in Linux, but it gave me errors in Windows due to character encoding. Solved.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

眼前雾蒙蒙 2024-11-15 01:44:25

您应该考虑在字符串之前添加 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 被解释为 tabformfeed

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

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

最清晰、最简单的解决方案是简单地添加一个 r



看起来您需要使用第二个解决方案,即正斜杠。 zipfile 库显然有点严格——考虑到这是一个仅限窗口的错误,它可能会悄悄溜过去。 (请参阅问题 6839)。

You should consider adding an r before the string to indicate it is a raw string -- the backslashes in the path are being interpreted as escape characters.

The following code:

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

produces the following output:

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

Note that the \t and \f are interpreted as tab and formfeed in the last line.

Interestingly, you could also change the backslashes to forward slashes (i.e. open("C:/path/to/folder"), which would work.

Or, escape the backslashes with ... backslashes (i.e. open("C:\\path\\to\\folder")).

IMO, the clearest and easiest solution is to simply add an r.


Edit:
It looks like you need to go with the second solution, forward slashes. The zipfile library is kind of strict apparently -- and given that this is a window-only bug, it probably snuck through. (See Issue 6839).

酒中人 2024-11-15 01:44:25

在这里找到我的问题的答案: 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!"

Found the answer to my question here: http://www.penzilla.net/tutorials/python/scripting.

I'm pasting the two functions that are relevant to zipping up a directory. The problem was not the string buffer, nor the slashes, but the way I was iterating and writing to the zipfile. These 2 recursive functions fix the problem. Iterating over the entire tree of sub-directories with os.walk is not a good way to write the archive.

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!"
唐婉 2024-11-15 01:44:25

您需要转义路径中的反斜杠。

尝试将以下内容更改为:

  • the_path= "C:\path\to\folder"the_path = "C:\\path\\to\\folder",并且
  • < code>zf.extractall("C:\destination\path") 到 zf.extractall("C:\\destination\\path")

You need to escape the backslashes in your paths.

Try changing the following:

  • the_path= "C:\path\to\folder" to the_path = "C:\\path\\to\\folder", and
  • zf.extractall("C:\destination\path") to zf.extractall("C:\\destination\\path").
一曲爱恨情仇 2024-11-15 01:44:25

即使在 Windows 上,您也可以使用正斜杠作为路径分隔符。我建议您在创建 zip 文件时尝试这样做。

You can use forward slashes as path separators, even on Windows. I suggest trying that when you create the zip file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文