I am FTPing a zip file from a remote FTP site using Python’s ftplib. I then attempt to write it to disk. The file write works, however most attempts to open the zip using WinZip or WinRar fail; both apps claim the file is corrupted. Oddly however, when right clicking and attempting to extract the file using WinRar, the file will extract.
So to be clear, the file write will work, but will not open inside the popular zip apps, but will decompress using those same apps. Note that the Python zipfile module never fails to extract the zips.
Here is the code that I’m using to get the zip file from the FTP site (please ignore the bad tabbing, that’s not the issue).
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()
Pass file.write directly inside the retrbinary function instead of passing appender. This will work and it will also not use that much RAM when you are downloading a big file.
If you’d like the data stored inside a variable though, you can also have a variable named:
Then pass to retrbinary instead of appender:
Your current appender function is wrong. += will not work correctly when there is binary data because it will try to do a string append and stop at the first NULL it sees.
As mentioned by @Lee B you can also use urllib2 or Curl. But your current code is almost correct if you make the small modifications I mentioned above.