Python zipfile未释放zip文件

5
我正在尝试在Windows 8.1和Python 2.7.9上使用zipfile库。 我想要在zipfile.open()之后删除library.zip,但os.remove()会抛出“WindowsError [Error 32]”,似乎zipfile没有在with块外释放zip文件。 WindowsError 32表示“进程无法访问文件,因为另一个进程正在使用该文件。” 那么,我该如何删除这个library.zip文件? 代码:
import os
import zipfile as z

dirs = os.listdir('build/')
bSystemStr = dirs[0]

print("[-] Merging library.zip...")
with z.ZipFile('build/' + bSystemStr + '/library.zip', 'a') as z1:
    with z.ZipFile('build_temp/' + bSystemStr + '/library.zip', 'r') as z2:
        for t in ((n, z2.open(n)) for n in z2.namelist()):
            try:
                z1.writestr(t[0], t[1].read())
            except:
                pass

print("[-] Cleaning temporary files...")
os.remove('build_temp/' + bSystemStr + '/library.zip')

错误:

[-]Merging library.zip...
...
build.py:74: UserWarning: Duplicate name: 'xml/sax/_exceptions.pyc'
  z1.writestr(t[0], t[1].read())
build.py:74: UserWarning: Duplicate name: 'xml/sax/expatreader.pyc'
  z1.writestr(t[0], t[1].read())
build.py:74: UserWarning: Duplicate name: 'xml/sax/handler.pyc'
  z1.writestr(t[0], t[1].read())
build.py:74: UserWarning: Duplicate name: 'xml/sax/saxutils.pyc'
  z1.writestr(t[0], t[1].read())
build.py:74: UserWarning: Duplicate name: 'xml/sax/xmlreader.pyc'
  z1.writestr(t[0], t[1].read())
build.py:74: UserWarning: Duplicate name: 'xmllib.pyc'
  z1.writestr(t[0], t[1].read())
build.py:74: UserWarning: Duplicate name: 'xmlrpclib.pyc'
  z1.writestr(t[0], t[1].read())
build.py:74: UserWarning: Duplicate name: 'zipfile.pyc'
  z1.writestr(t[0], t[1].read())
[-] Cleaning temporary files...
Traceback (most recent call last):
  File "build.py", line 79, in <module>
    os.remove('build_temp/' + bSystemStr + '/library.zip')
WindowsError: [Error 32] : 'build_temp/exe.win32-2.7/library.zip'

如果你根本没有使用 zipfile 打开它,你能删除这个 zip 文件吗?也许创建该 zip 文件的代码(你没有展示)正在保持它处于打开状态。 - interjay
这个程序相关的内容是:“从这个错误中的简短示例是否给您带来了相同的错误?” - Uyghur Lives Matter
2
您使用了“t[1]”对文件的悬空引用。我会将循环重写为“for n in z2.namelist()”。然后使用“with z2.open(n) as t”和“z1.writestr(n,t.read())”。这样,内部的文件将会被自动关闭。 - Eryk Sun
@eryksun 你说得对,谢谢。 - Nesswit
1个回答

2

在删除或退出程序之前,根据Python文档https://docs.python.org/2/library/zipfile.html#zipfile.ZipFile.close,我认为您必须关闭存档文件。

因此,在删除存档文件之前,请运行z1.close()z2.close()

您的代码应该像这样:

import os
import zipfile as z

dirs = os.listdir('build/')
bSystemStr = dirs[0]

print("[-] Merging library.zip...")
with z.ZipFile('build/' + bSystemStr + '/library.zip', 'a') as z1:
    with z.ZipFile('build_temp/' + bSystemStr + '/library.zip', 'r') as z2:
        for t in ((n, z2.open(n)) for n in z2.namelist()):
            try:
                z1.writestr(t[0], t[1].read())
            except:
                pass

         z2.close()

     z1.close()


print("[-] Cleaning temporary files...")
os.remove('build_temp/' + bSystemStr + '/library.zip')

如果我错了,请纠正我。

自Python 2.7起,close()由上下文管理器自动调用。 https://docs.python.org/3/library/zipfile.html#zipfile.ZipFile - AJ Slater

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接