4

我使用 Python 3.3 编写了 .zip 文件的下载和解压缩脚本。如果 .zip 的名称保持不变,这将毫无问题。如果我尝试在下载时更改 .zip 的名称,则zipfile.is_zipfile()不会将该文件识别为 .zip 文件 [尽管它仍会在 WinRAR 中解压缩]。

我通过传递shutil.copyfileobj()不同的 fdst 名称(不是整个路径)来更改名称。

使用的下载代码为:

import urllib.request
import shutil
import os, os.path



def mjd_downloader(url, destdir, destfilename=None):

    req = urllib.request.Request(url)
    response = urllib.request.urlopen(req)

    #if no filename passed by destfilename, retrieve filename from ulr
    if destfilename is None:
        #need to isolate the file name from the url & download to it
        filename = os.path.split(url)[1]

    else:
        #use given filename
        filename = destfilename


    #'Download': write the content of the downloaded file to the new file

    shutil.copyfileobj(response, open(os.path.join(destdir,filename), 'wb')) 

使用的解压码是:

import zipfile
from zipfile import ZipFile
import os, os.path
import shutil

def mjd_unzipper(zippathname, outfilebasename=None):
    #outfilebasename is a name passed to the function if a new name for 
    #the content is requried   
    if zipfile.is_zipfile(zippathname) is True:
        zfileinst = ZipFile(zippathname, 'r')
        zfilepath = os.path.split(zippathname)[0]
        zlen = len(zfileinst.namelist())
        print("File path: ", zfilepath)

        if outfilebasename is not None:
            for filename in zfileinst.namelist():
                memtype = os.path.splitext(filename)[1]
                outfilename = os.path.join(outfilebasename + memtype)
                print("Extracting: ", filename, " - to: ", outfilename)
                #curzfile = zfileinst.read(filename)
                curzfile = zfileinst.open(filename)
                shutil.copyfileobj(curzfile, open(
                    os.path.join(zfilepath, outfilename), 'wb'))
        else:
            for i in range(zlen):
                extractfile = zfileinst.namelist()[i]
                memtype = os.path.splitext(extractfile)[1]
                zfileinst.extract(extractfile, path = zfilepath)

        zipfile.ZipFile.close(zfileinst)
    else:
        print("Is not a zipfile")
        pass 

欢迎任何想法。

4

1 回答 1

0

我认为您的文件从未关闭:在下载脚本的第 24 行,您打开了目标文件以写入二进制数据。只有当您调用close()同一个文件时,数据才会从内存推送到文件(也有在不关闭文件的情况下调用的方法,但我现在不记得了)。

通常,最好使用以下with语句打开文件对象:

with open(os.path.join(destdir,filename), 'wb') as f:
    shutil.copyfileobj(response, f)

当该with语句与文件对象一起使用时,它会在块的末尾自动关闭它们,如果您曾经break离开块,或者如果由于任何其他原因离开了块(可能是导致解释器退出的未处理异常) .

如果您不能使用该with语句(我认为一些较旧的 Python 版本不支持将其与文件对象一起使用),您可以在完成后对对象调用 close() :

f = open(os.path.join(destdir,filename), 'wb')
shutil.copyfileobj(response, f)
f.close()

我希望这就是原因,因为那将是一个简单的修复!

于 2013-01-27T21:47:23.250 回答