Python解压文件并更新wxPython状态栏

2 投票
2 回答
1417 浏览
提问于 2025-04-16 15:12

我有几个很大的压缩文件,这些文件里有一套目录结构,我必须保持这个结构不变。目前我解压这些文件的方法是

    zip = zipfile.ZipFile(self.fileName)        
    zip.extractall(self.destination)
    zip.close()

问题是,这个过程可能需要3到5分钟,而且我没有任何反馈来告诉我它们还在工作。我想做的是在我的图形界面的状态栏上显示当前正在解压的文件名。我想的方式是这样的

    zip = zipfile.ZipFile(self.fileName)
    zipNameList = zipfile.namelist(self.fileName)
    for item in zipNameList:
        self.SetStatusText("Unzipping" + str(item))
        zip.extract(item)
    zip.close()

但这样做的问题是,它不能正确创建目录结构。我不确定这是不是最好的方法。

我还考虑过使用wx.progressdialog,但我找不到办法让它显示zip.extractall(filename)的进度。

2 个回答

0

你可以用 infolist 来代替 namelist。根据文档的说明:

如果你打开的是一个已经存在的压缩文件,里面的对象顺序和它们在实际的ZIP文件中的顺序是一样的。

另外,还有一个注意事项:

open()、read() 和 extract() 这些方法可以接受文件名或者 ZipInfo 对象。当你尝试读取一个包含重复名称的文件时,你会发现这个功能很有用。

所以你可以写类似这样的代码:

with ZipFile(zip_file_name) as myzipfile:
    members = myzipfile.infolist()
        for i, member in enumerate(members):
            myzipfile.extract(member, destination_path)
            self.SetStatusText("Unziping " + str(i))
            self.mysignal.emit(i) # use this to update inside a thread

你可以把这个放在一个线程里,然后通过信号来更新,SetStatusText 方法应该在对应的槽函数里面被调用。

3

我找到了一个可以接受的解决方案——不过我觉得最终还是希望它能支持多线程。

def unzipItem(self, fileName, destination)
    print "--unzipItem--"
    zip = zipfile.ZipFile(fileName)
    nameList = zip.namelist()

    #get the amount of files in the file to properly size the progress bar
    fileCount = 0
    for item in nameList:
        fileCount += 1

    #Built progress dialog
    dlg = wx.ProgressDialog("Unziping files",
                           "An informative message",
                           fileCount,
                           parent = self,
                           )

    keepGoing = True
    count = 0

    for item in nameList:
        count += 1
        dir,file = os.path.split(item)
        print "unzip " + file

        #update status bar
        self.SetStatusText("Unziping " + str(item))
        #update progress dialog
        (keepGoing, skip) = dlg.Update(count, file)
        zip.extract(item,destination)

    zip.close()

撰写回答