Getting TypeError when trying to download .zip from FTP server
سؤال
I am trying to download a .zip file from a FTP server and I keep getting this error:
File "C:/filename.py", line 37, in handleDownload
file.write(block)
TypeError: descriptor 'write' requires a 'file' object but received a 'str'
Here's my code (borrowed from http://postneo.com/stories/2003/01/01/beyondTheBasicPythonFtplibExample.html):
def handleDownload(block):
file.write(block)
print ".",
ftp = FTP('ftp.godaddy.com') # connect to host
ftp.login("auctions") # login to the auctions directory
print ftp.retrlines("LIST")
filename = 'auction_end_tomorrow.xml.zip'
file = open(filename, 'wb')
ftp.retrbinary('RETR ' + filename, handleDownload)
file.close()
ftp.close()
المحلول
I can't reproduce this myself, but I have an idea of what's happening -- I'm just not sure how it's happening. Hopefully someone can chime in. Note that file
isn't passed through to handleDownload, and file
is also the name of a builtin type. If file
were left as the builtin, then you'd get exactly this error:
>>> file
<type 'file'>
>>> file.write("3")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: descriptor 'write' requires a 'file' object but received a 'str'
So I think some of the problem is a confusion between file
, the built-in, and file
, the opened file itself. (Probably using a name other than "file"
is a good idea here.) Anyway, if you simply use
ftp.retrbinary('RETR ' + filename, file.write)
and ignore the handleDownload
function entirely, it should work. Alternatively, if you wanted to keep the dots printing every block, you could be a little fancier, and write something like
def handleDownloadMaker(openfile):
def handleDownload(block):
openfile.write(block)
print ".",
return handleDownload
which is a function which returns a function that points at the right file. After that,
ftp.retrbinary('RETR' + filename, handleDownloadMaker(file))
should work too.