我使用Python的ftplib从远程FTP站点FTP文件。然后我尝试将其写入磁盘。文件写入工作,但大多数尝试使用WinZip或WinRar打开zip失败;这两个应用声称该文件已损坏。然而奇怪的是,当右键单击并尝试使用WinRar提取文件时,文件将提取。
所以要明确的是,文件写入将起作用,但不会在流行的zip应用程序中打开,但将使用相同的应用程序进行解压缩。请注意,Python zipfile模块从不无法提取拉链。
以下是我用来从FTP站点获取zip文件的代码(请忽略错误的标签,这不是问题)。
filedata = None
def appender(chunk):
global filedata
filedata += chunk
def getfile(filename):
try:
ftp = None
try:
ftp = FTP(address)
ftp.login('user', 'password')
except Exception, e:
print e
command = 'RETR ' + filename
idx = filename.rfind('/')
path = filename[0:idx]
ftp.cwd(path)
fileonly = filename[idx+1:len(filename)]
ftp.retrbinary('RETR ' + filename, appender)
global filedata
data = filedata
ftp.close()
filedata = ''
return data
except Exception, e:
print e
data = getfile('/archives/myfile.zip')
file = open(pathtoNTFileShare, 'wb')
file.write(data)
file.close()
答案 0 :(得分:2)
直接在retrbinary函数内传递file.write而不是传递appender。这将起作用,当您下载大文件时它也不会使用那么多RAM。
如果您希望存储在变量中的数据,您还可以使用名为:
的变量blocks = []
然后传递给retrbinary而不是appender:
blocks.append
您当前的appender功能是错误的。当存在二进制数据时,+ =将无法正常工作,因为它将尝试执行字符串追加并在它看到的第一个NULL处停止。
如@Lee B所述,您也可以使用urllib2或Curl。但是,如果您进行上面提到的小修改,那么您当前的代码几乎是正确的。
答案 1 :(得分:1)
我从未使用过那个库,但urllib2工作正常,而且更直接。卷曲更好。
看看你的代码,我可以看到一些错误。您的异常捕获仅打印异常,然后继续。对于没有获得FTP连接的致命错误,他们需要打印消息然后退出。此外,你的filedata以None开头,然后你的appender使用+ =来添加,所以你试图追加一个字符串+ None,当我在这里尝试它时会产生一个TypeError。我很惊讶它正在工作;我猜想appender会抛出一个异常,所以FTP副本会中止。
在重读时,我刚刚注意到关于在二进制数据上使用+ =的另一个答案。那可能就是这样; python有时候会变得聪明,并且当你加入带有空格或NUL的字符串时,可能会“帮助”,或类似的东西。你最好的办法是让文件打开(让我们把它称为outfile),并使用你的appender只是outfile.write(chunk)。