使用 python 的 ftplib 同步目录
我正在学习 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...
非常感谢您的帮助!
I'm learning python and trying to write a code to sync two directories: one is on ftp server, the other is on my local disk. So far, I wrote a working code but I have a question or two about it :)
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
This piece of code should make two python lists: a list of files in local directory and a list of files in ftp directory. After removing duplicates from lists, the script should download 'missing' files to my local directory.
For now, this piece of code is doing what I need, but I have noticed that when I run it my output is not acting how I imagine it would act :)
For example, my current output goes:
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...
but I imagine that it should work like this:
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...
As I said, I just started to learn python, and maybe I'm doing some stuff here completely wrong (if str(s).startswith('226')
????). Maybe I cannot achieve this withftplib
only? So in the end my questions are:
What am I doing wrong here? :)
How to produce 'proper' output and is there a way to print some kind of status while downloading a file (at least a line of dots), for example:
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...
Thanks a lot for helping!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
retrybinary 块直到完成。这就是为什么您会立即看到
Processing ZZZ\n OK
,因为它发生在对 retrbinary 的调用完成之后。如果您想为每次调用打印
.
,那么您需要提供一个回调函数来执行此操作。这是 retrbinary 的文档字符串:因此,您需要提供一个不同的回调来写入文件并打印出“。”
您可能需要编辑该代码片段,但它应该让您了解该怎么做。
retrybinary blocks until it is complete. This is why you see
Processing ZZZ\n OK
immediately, because it occurs after the call to retrbinary has completed.If you want to print
.
for each call, then you need to provide a callback function to do this. here is the docstring for retrbinary:So, you need to provide a different callback that both writes the file and prints out '.'
You may have to edit that snippet of code, but it ought to give you an idea of what to do.