2

在没有回答我之前的问题的情况下。

我正在使用多线程通过控制套接字保持大型 FTP 传输。

不幸的是,这需要使用 ftplib.ftp.transfercmd()(而不是不提供显式套接字控制的 FTP.retrbinary()),它专门返回数据套接字并允许您发送“NOOP”命令而不会阻塞。

这是一个问题,因为 transfercmd("RETR" ...) 默认以 ASCII 模式进行 dwonloading,这会破坏我尝试下载的视频文件。

我已经搜索了所有 Ican 以找到明确的 BINARY 模式命令,但无济于事。有任何想法吗?

这是我的下载代码

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')
4

1 回答 1

5

正如retrbinary()'s source所暗示的,您必须使用以下命令告诉 FTP 服务器您想要二进制文件TYPE I

ftp.voidcmd('TYPE I')
# Do the transfer here

retrbinary实际上为您进行了传输,但似乎没有更新连接以防止其关闭。

您也不需要线程,只需将 ftp.voidcmd('NOOP') 放入下载循环中:

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()
于 2013-10-31T12:06:51.080 回答