1. 程式人生 > >Python--使用執行緒--批量檔案的移動 以及FTP共享自己資料夾

Python--使用執行緒--批量檔案的移動 以及FTP共享自己資料夾

在寫程式碼中 偶爾會遇到一些指令碼和方法,有時候這些指令碼程式都是用到再寫。這無疑浪費了自己很多時間,自己寫過一次為了防止程式碼的丟失不如放在部落格上記錄一下,如果再用到那邊直接用。

第一個 小知識點os模組的具體應用

"""
我們知道有時候需要大批的檔案從一個檔案家轉移到另外一個資料夾下,可能僅僅只能通過檔案的複製和剪下到另外一個資料夾下
但是在Linux下如果你想要轉移的資料夾以及資料夾下的檔案比較多怎麼辦?通過直接命令你會發現會報一個錯誤就是太大了,移動不了,
這裡也不說那個命令是什麼了。
ok今天的程式碼就是幫你解決這個問題。

本程式碼支援Linux和windows下。
解決檔案目錄總共是兩層的資料夾。如果資料夾目錄包含三層 暫不解決思路同如下。
"""
import os
import shutil

source_floder = r'D:\source'  # 將要移動的目標檔案的位置
target_floder = r'D:\target'  # 移動到的目標資料夾位置

floder_list = os.listdir(source_floder)  # 列出資料夾下所有的目錄與檔案
for each_floder in floder_list:  # 遍歷每個資料夾下所有檔案和資料夾
    if not os.path.exists(os.path.join(target_floder, each_floder)):  # 如果目標檔案不存在此資料夾建立
        os.mkdir(os.path.join(target_floder, each_floder))
        file_list = os.listdir(os.path.join(source_floder, each_floder))
        for each_file in file_list:  # 迴圈子資料夾下所有的檔案
            f_src = os.path.join(source_floder, each_floder, each_file)  # 將要移動的檔案
            if not os.path.exists(os.path.join(target_floder, each_floder, each_file)):  # 判斷目標資料夾中此檔案是否存在
                print('正在移動資料夾')
                f_dst = os.path.join(target_floder, each_floder, each_file)
                shutil.move(f_src, f_dst)  # 不存在移動
            else:
                print('this %s 檔案已經存在' % each_file)
                continue
    else:  # 如果資料夾已經存在,判斷檔案是否存在資料夾下。同上。
        file_list = os.listdir(os.path.join(source_floder, each_floder))
        for each_file in file_list:
            f_src = os.path.join(source_floder, each_floder, each_file)
            if not os.path.exists(os.path.join(target_floder, each_floder, each_file)):
                f_dst = os.path.join(target_floder, each_floder, each_file)
                print('正在移動資料夾')
                shutil.move(f_src, f_dst)
            else:
                print('this %s 檔案已經存在' % each_file)
                continue
    shutil.rmtree(os.path.join(source_floder, each_floder))  # 當一個資料夾中的所有檔案移除結束後。刪除這個資料夾

   
os模組有問題的推薦參考:http://www.cnblogs.com/renpingsheng/p/7065565.html

第二個小應用。FTP共享自己資料夾
當同事之間互相需要對方電腦軟體的時候而又苦於公司沒有共享盤, 忘記帶行動硬碟,U盤的時候不怕本文來幫助你實現。

from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer

# 例項化一個虛擬authorizer
authorizer = DummyAuthorizer()
# 新增一個匿名使用者,並給予其訪問某共享#資料夾的許可權(以D://folder為例)
authorizer.add_anonymous(r'D://')
# 建立handler. 例項化一個FTPServer必須給定一個handler,這裡按照文件的例子來就行。
handler = FTPHandler
handler.authorizer = authorizer
# 開啟伺服器。
# YOUR_IP_ADDRESS是你本機的內網#IP,可以用命令列命令 ipconfig 查到。
# 21是FTP協議的預設埠,一般不用修改。
server = FTPServer(('IP', 21), handler)
server.serve_forever()
請注意一定要把自己的防火牆關一下,不然是沒辦法進行共享的。
當然除了這個共享資料夾還有更厲害更簡單的呢。
例如我想共享D盤下Image資料夾的東西。

第一步:進入想要共享的資料夾
	   cd D:\Image
第二步:window+R cmd命令後 執行以下命令:
	   python3 -m http.server  # python3執行這個命令
	   python -m SimpleHTTPServer # python2執行此命令
親自試 可行。分享給你。

好了。這就是今天的一點點應用,如果有更好的方法,歡迎討論指出。

後記

2018-11-12
這幾天想了一下,就算實現了這個批量移動檔案。但是速度還是提不上去呀!!怎麼辦?能不能利用執行緒來搞一波呢?
既然想了就去搞,還好寫了出來,分享給大家。

import os
import shutil
import threadpool
from retry import retry


@retry(2)
def move_file(each_floder):
    each_split = each_floder.split('-')[:-5]
    tar_each = '-'.join(each_split)
    try:
        if not os.path.exists(os.path.join(target_floder, tar_each)):  # 如果目標檔案不存在此資料夾建立
            os.mkdir(os.path.join(target_floder, tar_each))
            file_list = os.listdir(os.path.join(source_floder, each_floder))
            for each_file in file_list:
                f_src = os.path.join(source_floder, each_floder, each_file)
                if not os.path.exists(os.path.join(target_floder, tar_each, each_file)):
                    print('正在移動資料夾')
                    f_dst = os.path.join(target_floder, tar_each, each_file)
                    shutil.move(f_src, f_dst)
                else:
                    print('this %s 檔案已經存在' % each_file)
                    continue
        else:
            file_list = os.listdir(os.path.join(source_floder, each_floder))
            for each_file in file_list:
                f_src = os.path.join(source_floder, each_floder, each_file)
                if not os.path.exists(os.path.join(target_floder, tar_each, each_file)):
                    f_dst = os.path.join(target_floder, tar_each, each_file)
                    print('正在移動資料夾')
                    shutil.move(f_src, f_dst)
                else:
                    print('this %s 檔案已經存在' % each_file)
                    continue
        shutil.rmtree(os.path.join(source_floder, each_floder))
    except BaseException as e:
        print(e)


if __name__ == '__main__':
    source_floder = # 將要移動的目標檔案的位置
    target_floder = # 移動到的目標資料夾位置
    task_pool = threadpool.ThreadPool(40)  # 準備5個執行緒池
    falg = 1
    while falg:
        try:
            requests = threadpool.makeRequests(move_file, os.listdir(source_floder))
            for req in requests:
                task_pool.putRequest(req)
            task_pool.wait()
        except BaseException as e:
            print(e)
        if len(os.listdir(source_floder)) == 0:
            falg = 0

注意其中幾點:執行緒可能導致搶佔資源從而會出現一些具體的問題。具體什麼問題是根據你的需求可能會出現的。這裡就不講了。出現問題需要你認真解決一下。