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

Posted

技术标签:

【中文标题】通过 FTP 下载时无法识别 Zip 文件【英文标题】:Zip-file not recognized when downloaded through FTP 【发布时间】:2018-10-10 18:30:26 【问题描述】:

我正在尝试创建一个脚本,该脚本将下载 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】:

可能是因为这种不好的做法单线:

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 块时文件被刷新和关闭(当然,在这个块之外执行文件读取操作)。

【讨论】:

啊,这很有道理!它奏效了。非常感谢您快速而准确的回复!

以上是关于通过 FTP 下载时无法识别 Zip 文件的主要内容,如果未能解决你的问题,请参考以下文章

WinSCP .NET 程序集无法识别 Session.PutFiles 中的 FTP 链接/URL

无法让 Eclipse 识别我的插件

coco图像识别无法使用

apk文件二维码微信无法识别 APP在微信中二维码扫描无法下载的解决方案

Cordova/Phonegap 无法识别 FileTransfer

安卓手机微信不能打开App下载地址的问题 apk文件二维码微信无法识别