2012-11-15 26 views
4

我使用Python 3.3編寫了一個下載並解壓縮.zip文件。如果.zip的名稱保持不變,這可以毫無問題地工作。如果我嘗試在下載時更改.zip的名稱,那麼zipfile.is_zipfile()將不會將該文件識別爲.zip文件[雖然它仍然在WinRAR中解壓縮]。Python 3.3:如果在下載時更改名稱,則不會識別.zip

我通過傳遞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 

任何想法歡迎。

+3

您有與擴展名不同的問題。 'zipfile.is_zipfile()'方法測試文件中包含的* data *,而不是文件名。我懷疑在文件的開頭或結尾有一些額外的數據,這可能會導致'zipfile.is_zipfile()'被大多數壓縮工具忽略。 –

+0

是的,我會找到文件系統上的文件,並實際比較二進制內容 - 差異應該工作。他們可能不同。 –

回答

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

我希望這是原因,因爲那將是一個簡單的修復!