使用 python 的 ftplib 同步目录
-
14-11-2019 - |
题
我正在学习 python 并尝试编写代码来同步两个目录:一个在 ftp 服务器上,另一个在我的本地磁盘上。到目前为止,我编写了一个工作代码,但我有一两个问题:)
import os
from ftplib import FTP
h_local_files = [] # create local dir list
h_remote_files = [] # create remote dir list
h_local = 'C:\\something\\bla\\' # local dir
ftp = FTP('ftp.server.com')
ftp.login('user', 'pass')
if os.listdir(h_local) == []:
print 'LOCAL DIR IS EMPTY'
else:
print 'BUILDING LOCAL DIR FILE LIST...'
for file_name in os.listdir(h_local):
h_local_files.append(file_name) # populate local dir list
ftp.sendcmd('CWD /some/ftp/directory')
print 'BUILDING REMOTE DIR FILE LIST...\n'
for rfile in ftp.nlst():
if rfile.endswith('.jpg'): # i need only .jpg files
h_remote_files.append(rfile) # populate remote dir list
h_diff = sorted(list(set(h_remote_files) - set(h_local_files))) # difference between two lists
for h in h_diff:
with open(os.path.join(h_local,h), 'wb') as ftpfile:
s = ftp.retrbinary('RETR ' + h, ftpfile.write) # retrieve file
print 'PROCESSING', h
if str(s).startswith('226'): # comes from ftp status: '226 Transfer complete.'
print 'OK\n' # print 'OK' if transfer was successful
else:
print s # if error, print retrbinary's return
这段代码应该创建两个 python 列表:本地目录中的文件列表和 ftp 目录中的文件列表。从列表中删除重复项后,脚本应将“丢失”文件下载到我的本地目录。
目前,这段代码正在执行我需要的操作,但我注意到当我运行它时,我的输出并没有按照我想象的方式运行:)
例如,我当前的输出是:
PROCESSING 2012-01-17_07.05.jpg
OK
# LONG PAUSE HERE
PROCESSING 2012-01-17_07.06.jpg
OK
# LONG PAUSE HERE
PROCESSING 2012-01-17_07.06.jpg
OK
etc...
但我想它应该像这样工作:
PROCESSING 2012-01-17_07.05.jpg
# LONG PAUSE HERE (WHILE DOWNLOADING)
OK
PROCESSING 2012-01-17_07.06.jpg
# LONG PAUSE HERE (WHILE DOWNLOADING)
OK
PROCESSING 2012-01-17_07.06.jpg
# LONG PAUSE HERE (WHILE DOWNLOADING)
OK
etc...
正如我所说,我刚刚开始学习Python,也许我在这里做的一些事情完全错误(if str(s).startswith('226')
???)。也许我无法实现这一目标ftplib
仅有的?所以最后我的问题是:
我在这里做错了什么?:)
如何产生“正确的”输出以及有没有办法在下载文件时打印某种状态(至少一行点),例如:
PROCESSING 2012-01-17_07.05.jpg
..........
OK
PROCESSING 2012-01-17_07.06.jpg
......
OK
PROCESSING 2012-01-17_07.06.jpg
...............
OK
etc...
非常感谢您的帮助!
解决方案
retrybinary 块直到完成。这就是为什么你会看到 Processing ZZZ\n OK
立即,因为它发生在对 retrbinary 的调用完成之后。
如果您想打印 .
对于每个调用,您需要提供一个回调函数来执行此操作。这是 retrbinary 的文档字符串:
"""Retrieve data in binary mode. A new port is created for you.
Args:
cmd: A RETR command.
callback: A single parameter callable to be called on each
block of data read.
blocksize: The maximum number of bytes to read from the
socket at one time. [default: 8192]
rest: Passed to transfercmd(). [default: None]
Returns:
The response code.
"""
因此,您需要提供一个不同的回调来写入文件并打印出“。”
import sys # At the top of your module.
# Modify your retrbinary
ftp.retrbinary('RETR ' + h, lambda s: ftpfile.write(s) and sys.stdout.write('.'))
您可能需要编辑该代码片段,但它应该让您了解该怎么做。
不隶属于 StackOverflow