Reputation: 2612
in the absence of an answer to my previous question.
I am using multihtreading to keep a large FTP transfer alive via the control socket.
Unfortuantely this requires the use of ftplib.ftp.transfercmd() (rather than FTP.retrbinary() which does not give explicit socket control) which returns the data socket exclusively and allows you to send 'NOOP' commands without blocking.
This is a problem as transfercmd("RETR" ...) defaults to dwonloading in ASCII mode which corrupts the video files I'm trying to download.
I have scoured everything Ican to find an explicit BINARY mode command to no avail. Any ideas?
heres is my download code
def downloadFile(filename, folder):
#login
ftp = FTP(myhost,myuser,passw)
ftp.set_debuglevel(2)
sock = ftp.transfercmd('RETR ' + filename)
def background():
f = open(folder + filename, 'wb')
while True:
block = sock.recv(1024*1024)
if not block:
break
f.write(block)
sock.close()
t = threading.Thread(target=background)
t.start()
while t.is_alive():
t.join(60)
ftp.voidcmd('NOOP')
Upvotes: 2
Views: 6942
Reputation: 1853
As retrbinary()
's source suggests you have to tell the FTP server you want binary with the TYPE I
command:
ftp.voidcmd('TYPE I')
# Do the transfer here
retrbinary
actually does the transfer for you, but doesn't seem to update the connection to keep it from closing.
Also you don't need a thread, just put ftp.voidcmd('NOOP') in the download loop:
def downloadFile(filename, folder):
#login
ftp = FTP(myhost,myuser,passw)
ftp.set_debuglevel(2)
ftp.voidcmd('TYPE I')
sock = ftp.transfercmd('RETR ' + filename)
f = open(folder + filename, 'wb')
while True:
block = sock.recv(1024*1024)
if not block:
break
ftp.voidcmd('NOOP')
f.write(block)
sock.close()
Upvotes: 5