Python 使用ftplib和多处理上传多个文件
我正在尝试使用ftp删除多个文件。但是,它不是上载多个不同的文件,而是多次上载一个文件。怎么了Python 使用ftplib和多处理上传多个文件,python,multithreading,python-2.7,multiprocessing,Python,Multithreading,Python 2.7,Multiprocessing,我正在尝试使用ftp删除多个文件。但是,它不是上载多个不同的文件,而是多次上载一个文件。怎么了 import fnmatch import os from multiprocessing import Pool import ftplib file_extensions = [ '*.mp4', '*wmv' ] matches = [] #match = [] exclude = "/ext_hdd/download/incomplete" def upload(file): ftp
import fnmatch
import os
from multiprocessing import Pool
import ftplib
file_extensions = [ '*.mp4', '*wmv' ]
matches = []
#match = []
exclude = "/ext_hdd/download/incomplete"
def upload(file):
ftp = ftplib.FTP('ftp.domain.com')
ftp.login("username","password")
f = open(match,'rb')
print ("uploading" + match)
ftp.storbinary('STOR %s' %match, f)
f.close()
ftp.quit()
for root, dirs, filenames in os.walk("/ext_hdd/download"):
dirs[:] = [d for d in dirs if d not in exclude]
for extension in file_extensions:
for filename in fnmatch.filter(filenames, extension):
matches.append(os.path.join(root, filename))
(match for match in matches if file_size > 209715200)
#print matches
for match in matches:
pool = Pool(2)
pool.map(upload,match)
有几个问题。首先,迭代给定目录中与特定文件扩展名匹配的所有文件,并将其添加到名为
matches
的列表中。但是,在for循环中,您还迭代了匹配项
,并对每个项调用Pool.map
。这意味着如果您有两个匹配的文件,那么您的代码基本上与此等效:
for filename in ["file1.mp4", "file2.mp4"]:
matches.append(os.path.join(root, filename))
for match in matches:
pool_stuff(filename)
这会在filename
上调用pool\u stuff
两次,因为它会在匹配项上迭代两次。同样的事情也发生在你的代码上
第二个问题是,在内部循环的每次迭代中都要创建一个新的池
,这根本不是您想要做的。您只需要创建一次池
,并将所有匹配项传递给它。您也不需要使用map
,因为您一次只将一个任务传递给池
。相反,您可以使用apply_async
在迭代/筛选文件时传递任务。下面是一个经过清理的示例
import fnmatch
import os
from multiprocessing import Pool
import ftplib
file_extensions = [ '*.mp4', '*wmv' ]
exclude = "/ext_hdd/download/incomplete"
def upload(match):
ftp = ftplib.FTP('ftp.domain.com')
ftp.login("username","password")
f = open(match,'rb')
print ("uploading" + match)
ftp.storbinary('STOR %s' %match, f)
f.close()
ftp.quit()
if __name__ == "__main__":
pool = Pool(2)
tasks = []
for root, dirs, filenames in os.walk("/ext_hdd/download"):
for extension in file_extensions:
for filename in fnmatch.filter(filenames, extension):
match = os.path.join(root, filename)
tasks.append(pool.apply_async(upload, args=(match,)))
# Get the result of each task, just so any
# exceptions thrown in the workers will be raised.
for task in tasks:
task.get()
pool.close()
pool.join()
请注意,我从您的原始示例中删除了一些似乎没有实际用于任何用途的代码。x.get()到底是什么?另外,我应该在哪里插入ftplib部分?如果您可以修改我的示例代码,这将非常好,这可以帮助我了解整个情况,包括在哪里插入文件大小比较部分和ftp上载部分。谢谢。@ThomasG.Lau我已经更新了示例,以显示上传功能。希望这能澄清你的第二个问题x.get()
应该说task.get()
(很抱歉),这是对的调用。它用于等待传递给池的函数。应用\u async
完成,并返回其结果。我只是使用它,以便您查看上载中是否出现任何错误。如果您忽略了对task.get()
的调用,它们将以静默方式出现,这可能会造成混淆。@ThomasG.Lau文件大小
比较生成器表达式(如果文件大小>209715200,则在匹配中进行匹配)
实际上没有执行任何操作,因为您没有将其分配给变量或对其进行迭代,而且file\u size
在任何地方都没有定义,所以我删除了它。你真的想过滤掉某个大小以下的文件吗?您是否遗漏了实际计算文件大小的那一行?我实际上想过滤(忽略)特定大小的文件,我可能做错了,所以文件大小>209715200不起作用?如果我想在调试完成后静默地做一些事情,我应该注释掉哪一行?