Python中使用ftplib与os.unlink结合使用

3

使用以下代码,我将file.txt上传到FTP服务器。当文件上传完成后,我会在本地机器上将其删除。

import os
from ftplib import FTP

HOST = 'host.com'
FTP_NAME = 'username'
FTP_PASS = 'password'
filepath = 'C:\file.txt'
while True:
    try:
        ftp = FTP(HOST)
        ftp.login(FTP_NAME, FTP_PASS)
        file = open(filepath, 'r')
        ftp.storlines('STOR file.txt', file)
        ftp.quit()
        file.close() # from this point on the file should not be in use anymore
        print 'File uploaded, now deleting...'
    except all_errors as e: #EDIT: Got exception here 'timed out'
        print 'error'       #      then the upload restarted.
        print str(e)

os.unlink(filepath) # now delete the file

代码可以运行,但是有时(每上传10次左右)会出现以下错误信息:
Traceback (most recent call last):
in os.unlink(filepath)
WindowsError: [Error 32] The process cannot access the file
because it is being usedby another process: 'C:\file.txt'

所以文件无法被删除是因为“它还没有被释放”或者其他原因吗?我也试过这种方式来解除文件链接:
while True: # try to delete the file until it is deleted...
    try:
        os.unlink(filepath)
        break
    except all_errors as e:
        print 'Cannot delete the File. Will try it again...'
        print str(e)

但是使用“try except块”后,我仍然得到了相同的错误:“由于另一个进程正在使用文件,因此无法访问该文件”! 脚本甚至没有尝试打印异常:
'Cannot delete the File. Will try it again...'

我想知道如何使 os.unlink 正常工作?

谢谢!


你确定那个文件没有在文本编辑器中打开吗?还是已经打开了但是文本编辑器还没有关闭? - SilentGhost
抱歉,我忘记在ftplib中使用了while循环!不知道是否相关,但在STOR之后我收到了一个“超时”异常,然后ftp上传重新启动。在此之后,os.unlink无法工作(进程正在使用...)。 - creativz
all_errors 到底是什么?如果其中没有 WindowsError(或其超类),那么异常就不会被捕获。 - balpha
我想我应该用WindowsError替换all_errors吧?:> 鉴于ftpupload中的异常,os.unlink无法完成它的工作。不过通过“except WindowsError as e:”,“while delete loop”应该可以正常工作。 - creativz
好的,那么这与 ftplibos.unlink 没有任何关系。这只是使用了 all_errors - SilentGhost
你在哪里跳出 while True 循环? - SilentGhost
3个回答

0
import os
from ftplib import FTP

HOST = 'host.com'
FTP_NAME = 'username'
FTP_PASS = 'password'
filepath = 'C:\file.txt'
file = open(filepath, 'r')
while True:
    try:
        ftp = FTP(HOST)
        ftp.login(FTP_NAME, FTP_PASS)        
        ftp.storlines('STOR file.txt', file)
    except all_errors as e: #EDIT: Got exception here 'timed out'
        print 'error'       #      then the upload restarted.
        print str(e)
    else:
        ftp.quit()
        file.close() # from this point on the file should not be in use anymore
        print 'File uploaded, now deleting...'   
        os.unlink(filepath) # now delete the file
        break

0

我仍然有代码问题,它不够健壮,无法满足我的需求。

例如,登录过程可能会失败。也许用户名和密码错误,也许服务器繁忙。

try:
    ftp = FTP(HOST) # HOST is a valid host address
    ftp.login('test', 'test111111') # WRONG user + pass to test code robustness
    ftp.quit()
except all_errors as e:
    ftp.quit()
    print str(e)

问题在于 except 块中的 ftp.quit()。Python 返回以下错误(而不是异常):
Traceback (most recent call last):
    File "test.py", line 9, in <module>
        ftp.quit()
NameError: name 'ftp' is not defined

0

在try/except的except部分,你需要关闭(文件和ftp会话),否则文件将继续被“旧”的超时ftp会话引用(因此,作为结果,你需要在while循环内打开文件,而不是在外面)——仅在else部分关闭文件和ftp会话是不够的,因为这并不能摆脱来自失败的超时尝试(如果有的话)的引用。


把整个ftp上传代码放在一个新的def中,然后把os.unlink放在def之外(甚至是另一个def中),这样做可以解决ftp会话问题吗? - creativz
只要您确保文件和FTP会话无条件关闭(包括在超时发生时),无论它们是在同一个函数中还是另一个函数中,都不会有问题。 - Alex Martelli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接