Python的ftplib STOR可靠性如何?

1 投票
3 回答
3169 浏览
提问于 2025-04-15 17:59

我正在用这段代码把我的文件myfile.txt从Windows电脑上传到一个FTP服务器。上传完成后,脚本会删除我本地机器上的文件(我并没有在FTP上删除它)。

try:
    ftp = FTP(ftp.host.com)
    ftp.login(your_username, your_password)
    file = open(myfile.txt, "rb")
    ftp.storbinary('STOR myfile.txt', file)
    print 'STORing File now...'
    ftp.quit()
    file.close()
    subprocess.Popen('del myfile.txt', shell=True)
    print 'File deleted'
except all_errors:
    print 'An error occured'

这段代码可以运行,但不太可靠!大约每上传十次,就会有一次我的脚本在存储文件时卡住。

print 'STORing File now...' # So I just get 'STORING File now...'

这个文件不大,应该几秒钟就能上传完,但我经常要等一个小时甚至两个小时,才会出现异常:

print 'An error occured'

如果异常能早点出现就好了,这样我可以重新启动上传(比如用一个循环)。因为我需要尽快上传这个文件,所以我想让上传速度更快(我不想等那么久才看到异常)。

第二个问题是:有时候会出现这种情况:文件成功上传后,脚本却无法删除我本地机器上的文件,因为“某个其他进程已经在使用它”——我觉得是ftplib没有“释放”这个文件。我该怎么做才能防止这种情况发生呢?

我在寻找一个更好、更可靠的简单文件上传解决方案。有人有什么建议吗?谢谢!

3 个回答

1

为了更早地捕捉到错误,可以使用 socket.setdefaulttimeout,比如:

import socket
socket.setdefaulttimeout(20.0)

如果一个 socket 被阻塞了 20 秒,就会给你抛出一个错误。

如果你想从 Python 脚本中删除一个文件,可以使用 os.unlink,这比调用一个单独的进程来执行 del 要好得多。

2

不要使用子进程去调用命令行删除文件,直接用os.unlink这个方法就可以跨平台地完成这个操作(如果os.unlink不行,shutil库可以帮你解决问题)。

现在,你的错误信息被你那条无用的打印语句给吞掉了——应该获取异常的追踪信息,这样能给你很多线索。不过,你的问题很可能和socket超时有关——要么你没有使用被动FTP,要么服务器配置错误,给了你一个无效的被动连接端口号(可能是被它的防火墙给挡住了)。

2

这个怎么样

def upload(ftp, filename):
    ftp.storbinary("STOR " + filename, open(filename, "rb"), 1024)
try:
    ftp = FTP("ftp.host.com")
    ftp.login(your_username, your_password)
except Exception,e:
    print e
else:
    file = open("myfile.txt", "rb")
    print 'STORing File now...'
    try:
        upload(ftp,file)
    except Exception,e:
        print e
    else:
        ftp.quit()
        file.close()
        try:
            os.remove("myfile.txt")
        except Exception,e:
            print e
        else:
            print 'File deleted'

记住,Python有自己处理文件删除的模块。不要不必要地调用系统的删除命令。

撰写回答