这是我需要完成的事情: - 连接到FTP - 获取test.txt的内容 - 在获得结果后立即将新内容写入test.txt
在实际案例场景中,我需要获得preios修改时间,存储在txt文件中,然后只将那些在此之后修改过的文件上传到FTP而不专门检查每个文件(有数千个,那将是太长了。)
这就是我被困的地方。
def continueTest(data, ftp):
print(data, ftp)
with open('test.txt', 'w+') as file:
file.write('test')
with open('test.txt', 'rb') as file:
ftp.storbinary('STOR htdocs/test.txt', file)
def test():
host_data=FTP_HOSTS['planz-norwegian']
ftp = ftplib.FTP(host=host_data['server'],
user = host_data['username'],
passwd = host_data['password'])
print('connected to ftp')
ftp.retrbinary('RETR htdocs/test.txt', lambda data:continueTest(data, ftp))
if __name__=='__main__':
test()
输出:
connected to ftp
b'test' <ftplib.FTP object at 0x0322FAB0>
Traceback (most recent call last):
File "C:\Python33\Plan Z Editor SL\redistdb.py", line 111, in <module>
test()
File "C:\Python33\Plan Z Editor SL\redistdb.py", line 107, in test
ftp.retrbinary('RETR htdocs/test.txt', lambda data:continueTest(data, ftp))
File "C:\Python33\lib\ftplib.py", line 434, in retrbinary
callback(data)
File "C:\Python33\Plan Z Editor SL\redistdb.py", line 107, in <lambda>
ftp.retrbinary('RETR htdocs/test.txt', lambda data:continueTest(data, ftp))
File "C:\Python33\Plan Z Editor SL\redistdb.py", line 99, in continueTest
ftp.storbinary('STOR htdocs/test.txt', file)
File "C:\Python33\lib\ftplib.py", line 483, in storbinary
with self.transfercmd(cmd, rest) as conn:
File "C:\Python33\lib\ftplib.py", line 391, in transfercmd
return self.ntransfercmd(cmd, rest)[0]
File "C:\Python33\lib\ftplib.py", line 351, in ntransfercmd
host, port = self.makepasv()
File "C:\Python33\lib\ftplib.py", line 329, in makepasv
host, port = parse227(self.sendcmd('PASV'))
File "C:\Python33\lib\ftplib.py", line 873, in parse227
raise error_reply(resp)
ftplib.error_reply: 200 Type set to I.
如果我在回调中不使用STOR,一切正常,但是,我怎么能从RETR命令获取数据?
我知道可能的解决方案,但我确信必须有一个更优雅的解决方案:
- 使用urllib.request而不是RETR(如果服务器上没有HTTP,该怎么办?)
- 在回调函数中重新初始化FTP连接(由于等待服务器重新连接,可能比预期慢)
- 用户ftp.set_pasv(False)
(回调启动,但脚本未结束且无法使用ftp.quit()
或ftp.close()
)
答案 0 :(得分:2)
根据retrbinary的文件:
为每个接收的数据块调用回调函数,其中一个字符串参数给出数据块。
这表明在检索文件的数据连接仍处于打开状态且STOR命令尚未完成时调用回调。使用FTP无法创建新的数据连接(在同一个FTP会话中),而另一个仍处于活动状态。此外,看起来ftplib感到困惑,并认为TYPE I
对PASV
的响应的响应:
File "C:\Python33\lib\ftplib.py", line 873, in parse227
raise error_reply(resp)
ftplib.error_reply: 200 Type set to I.
你应该做的只是在RETR完成后调用STOR,即让回调存储文件中的所有内容,然后仅在retrbinary
返回后打开文件。
但是,我怎么能从RETR命令中获取数据呢?
在当前的回调中,您将数据存储在文件中,然后读取该文件。回调应该仍然将数据存储在文件中,但读取和调用STOR应该在回调之后完成,就在retrbinary
之后。您不能并行RETR和STOR数据。