通过FTP下载时无法识别Zip文件

时间:2018-10-10 18:30:26

标签: python python-2.7 zip zipfile

我正在尝试创建一个脚本,该脚本将下载一个ZIP文件并将其解压缩。

我正在Windows Server 2016上使用Python 2.7。

我创建了一个如下所示的下载脚本:

ftp = FTP()
ftp.connect("***")
ftp.login("***","***")
ftp.cwd(ftppath)
ftp.retrbinary("RETR " + filename ,open(tempfile, 'wb').write)
ftp.quit()

还有一个zip提取脚本:

zip_ref = zipfile.ZipFile(tempfile, 'r')
zip_ref.extractall(localpath)
zip_ref.close()

这些工作是独立进行的。含义:如果我在测试的ZIP文件上运行提取脚本,它将提取文件。另外,如果我从服务器运行FTP脚本,它将下载文件。

但是!如果我一起运行这些脚本,这意味着我从FTP服务器下载了文件然后解压缩,它将返回错误:“文件不是Zip文件”。

谁知道为什么会这样? 我检查了以下内容:

  • 正确的文件夹
  • 下载zip文件,解压缩并重新压缩(然后脚本将解压缩)

编辑

我一直在阅读有关IO字节之类的内容,但是在实现它方面没有任何运气。

1 个答案:

答案 0 :(得分:1)

可能是因为这种糟糕的一线做法:

ftp.retrbinary("RETR " + filename ,open(tempfile, 'wb').write)

open(tempfile, 'wb').write对于关闭文件的时间不提供任何保证。您不会在任何地方存储open返回的句柄,因此无法决定何时close文件(并确保完整的磁盘写入)。

因此,当尝试以读取模式打开文件时,文件的最后一部分可能还没有被写入磁盘。并且链接下载+解压缩会触发该错误(当2次单独执行留出了刷新和关闭文件的时间)

最好使用这样的上下文管理器:

with open(tempfile, 'wb') as f:
    ftp.retrbinary("RETR " + filename ,f.write)

因此,退出with块时,文件将被刷新并关闭(当然,在此块 之外执行文件读取操作)。