普通批量拷贝文件

import os
import shutil
import logging
from logging import handlers
from colorama import Fore, Style, init import sys
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR) # 加入环境变量
from utils.time_utils import run_time
from conf import settings class Colorlog(object):
"""
记录日志,添加颜色
"""
init(autoreset=True) # 初始化,并且设置颜色设置自动恢复 # 根据信息不同设置不同的颜色格式
info_color = Fore.GREEN + Style.BRIGHT
warn_color = Fore.YELLOW + Style.BRIGHT
debug_color = Fore.MAGENTA + Style.BRIGHT
error_color = Fore.RED + Style.BRIGHT def __init__(self, name):
# 日志格式
log_format = '[%(asctime)s - %(levelname)s - %(name)s ] %(message)s '
self.logger = logging.getLogger(name)
self.logger.setLevel(settings.LOG_LEVEL) console_handler = logging.StreamHandler()
# 文件绝对路径
logfile_path = os.path.join(settings.LOG_DIR, "log", settings.LOG_FILE)
if not os.path.exists(logfile_path):
# 创建log目录
os.mkdir(os.path.join(settings.LOG_DIR, "log"))
# 每天创建一个日志文件,文件数不超过20个
file_handler = handlers.TimedRotatingFileHandler(
logfile_path, when="D", interval=1, backupCount=20) self.logger.addHandler(console_handler)
self.logger.addHandler(file_handler) file_format = logging.Formatter(fmt=log_format)
console_format = logging.Formatter(
fmt=log_format, datefmt='%Y-%m-%d %H:%M:%S ') console_handler.setFormatter(console_format)
file_handler.setFormatter(file_format) def warn(self, message):
self.logger.warning(Colorlog.warn_color + message) def info(self, message):
self.logger.info(Colorlog.info_color + message) def error(self, message):
self.logger.error(Colorlog.info_color + message) def debug(self, message):
self.logger.debug(Colorlog.info_color + message) cp_log = Colorlog("cp") def copy_file(local_file_path, dst_file_path):
size = bytes2human(os.path.getsize(local_file_path))
# cp_log.debug(
# 'copy file {} to {}, file size {}'.format(
# local_file_path, dst_file_path, size))
shutil.copy(local_file_path, dst_file_path) # copy file @run_time
def upload_file(src_path, dst_path):
"""
上传文件
:param src_path:
:param dst_path:
:return:
"""
cp_log.info('upload_file %s %s' % (src_path, dst_path))
# 目标目录是否存在,不存在则创建
if not os.path.exists(dst_path):
os.makedirs(dst_path)
cp_log.info('Create Dest Dir %s' % dst_path) # 判断是否为目录,存在则把文件拷贝到目标目录下
if os.path.isdir(src_path):
all_file_nums = 0
for root, dirs, files in os.walk(src_path):
# 遍历目录下所有文件根,目录下的每一个文件夹(包含它自己),
# 产生3-元组 (dirpath, dirnames, filenames)【文件夹路径, 文件夹名字, 文件名称】
for f in files:
local_file_path = os.path.join(root, f) # 本地文件路径 如/src/q.txt
dst_file_path = os.path.abspath(
local_file_path.replace(
src_path, dst_path)) # 目标文件路径 如/dst/q.txt
dst_dir = os.path.dirname(dst_file_path) # 目标文件路径文件夹 如/dst/
if not os.path.isdir(dst_dir):
os.makedirs(dst_dir) # 创建目录
cp_log.debug('Create Dest Dir %s' % dst_path) copy_file(local_file_path, dst_file_path) # 拷贝文件
cp_log.info('copy file {} complete '.format(local_file_path))
all_file_nums += 1 cp_log.info(
'copy all files complete , files count = {}'.format(all_file_nums))
else:
cp_log.warn('Dir is not exists %s' % dst_path) def bytes2human(n):
symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
prefix = {}
for i, s in enumerate(symbols):
# << 左移” 左移一位表示乘2 即1 << 1=2,二位就表示4 即1 << 2=4,
# 10位就表示1024 即1 << 10=1024 就是2的n次方
prefix[s] = 1 << (i + 1) * 10
for s in reversed(symbols):
if n >= prefix[s]:
value = float(n) / prefix[s]
return '%.1f%s' % (value, s)
return "%sBytes" % n if __name__ == '__main__':
src = 'D://test1'
dst = 'D://copytest2'
upload_file(src, dst)

 

输出结果 

[2018-06-29 15:14:04  - INFO - cp  ] upload_file D://test1   D://copytest2
[2018-06-29 15:14:04 - INFO - cp ] Create Dest Dir D://copytest2
[2018-06-29 15:14:04 - DEBUG - cp ] Create Dest Dir D://copytest2
[2018-06-29 15:14:04 - INFO - cp ] copy file D://test1\20180601\20180601_test.txt complete
[2018-06-29 15:14:04 - DEBUG - cp ] Create Dest Dir D://copytest2
[2018-06-29 15:14:19 - INFO - cp ] copy file D://test1\20180601\wmv\01文件操作和异常.wmv.pbb complete
[2018-06-29 15:14:19 - DEBUG - cp ] Create Dest Dir D://copytest2
[2018-06-29 15:14:19 - INFO - cp ] copy file D://test1\20180602\20180602_test.txt complete
……
[2018-06-29 15:16:20 - INFO - cp ] copy file D://test1\Tesseract-OCR\tessdata\tessconfigs\nobatch complete
[2018-06-29 15:16:20 - INFO - cp ] copy file D://test1\Tesseract-OCR\tessdata\tessconfigs\segdemo complete
[2018-06-29 15:16:20 - INFO - cp ] copy all files complete , files count = 164
[2018-06-29 15:16:20 - DEBUG - runtime - time_utils.py - decor- 59 ] func {upload_file} run { 135.2727}s

  

使用多线程批量拷贝文件

#!/usr/bin/python
# -*- coding: utf-8 -*-
# @Time : 2018/6/29 10:28
# @Author : hyang
# @File : batch_copy.py
# @Software: PyCharm import os
import shutil
import logging
from logging import handlers
from colorama import Fore, Style, init
from multiprocessing.dummy import Pool as ThreadPool
import queue import sys
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR) # 加入环境变量
from utils.time_utils import run_time
from conf import settings class Colorlog(object):
"""
记录日志,添加颜色
"""
init(autoreset=True) # 初始化,并且设置颜色设置自动恢复 # 根据信息不同设置不同的颜色格式
info_color = Fore.GREEN + Style.BRIGHT
warn_color = Fore.YELLOW + Style.BRIGHT
debug_color = Fore.MAGENTA + Style.BRIGHT
error_color = Fore.RED + Style.BRIGHT def __init__(self, name):
# 日志格式
log_format = '[%(asctime)s - %(levelname)s - %(name)s ] %(message)s '
self.logger = logging.getLogger(name)
self.logger.setLevel(settings.LOG_LEVEL) console_handler = logging.StreamHandler()
# 文件绝对路径
logfile_path = os.path.join(settings.LOG_DIR, "log", settings.LOG_FILE)
if not os.path.exists(logfile_path):
# 创建log目录
os.mkdir(os.path.join(settings.LOG_DIR, "log"))
# 每天创建一个日志文件,文件数不超过20个
file_handler = handlers.TimedRotatingFileHandler(
logfile_path, when="D", interval=1, backupCount=20) self.logger.addHandler(console_handler)
self.logger.addHandler(file_handler) file_format = logging.Formatter(fmt=log_format)
console_format = logging.Formatter(
fmt=log_format, datefmt='%Y-%m-%d %H:%M:%S ') console_handler.setFormatter(console_format)
file_handler.setFormatter(file_format) def warn(self, message):
self.logger.warning(Colorlog.warn_color + message) def info(self, message):
self.logger.info(Colorlog.info_color + message) def error(self, message):
self.logger.error(Colorlog.info_color + message) def debug(self, message):
self.logger.debug(Colorlog.info_color + message) cp_log = Colorlog("cp") def copy_file(local_file_path, dst_file_path, q):
size = bytes2human(os.path.getsize(local_file_path))
# cp_log.debug(
# 'copy file {} to {}, file size {}'.format(
# local_file_path, dst_file_path, size))
shutil.copy(local_file_path, dst_file_path) # copy file
q.put(local_file_path) # 加入队列 @run_time
def upload_file(src_path, dst_path):
"""
上传文件
:param src_path:
:param dst_path:
:return:
"""
pool = ThreadPool(3) # 开启3个线程
q = queue.Queue() # 开启一个队列
cp_log.info('upload_file %s %s' % (src_path, dst_path))
# 目标目录是否存在,不存在则创建
if not os.path.exists(dst_path):
os.makedirs(dst_path)
cp_log.info('Create Dest Dir %s' % dst_path) # 判断是否为目录,存在则把文件拷贝到目标目录下
if os.path.isdir(src_path):
all_file_nums = 0
for root, dirs, files in os.walk(src_path):
# 遍历目录下所有文件根,目录下的每一个文件夹(包含它自己),
# 产生3-元组 (dirpath, dirnames, filenames)【文件夹路径, 文件夹名字, 文件名称】
for f in files:
all_file_nums += 1
local_file_path = os.path.join(root, f) # 本地文件路径 如/src/q.txt
dst_file_path = os.path.abspath(
local_file_path.replace(
src_path, dst_path)) # 目标文件路径 如/dst/q.txt
dst_dir = os.path.dirname(dst_file_path) # 目标文件路径文件夹 如/dst/
if not os.path.isdir(dst_dir):
os.makedirs(dst_dir) # 创建目录
cp_log.debug('Create Dest Dir %s' % dst_path)
pool.apply_async(
func=copy_file, args=(
local_file_path, dst_file_path, q)) pool.close() # close()执行后不会有新的进程加入到pool
# pool.join() # join函数等待所有子进程结束 print('all_file_nums ', all_file_nums)
num = 0
while True:
if not q.empty():
item = q.get()
cp_log.info('copy file {} complete '.format(item))
num += 1
copy_rate = float(num / all_file_nums) * 100
cp_log.warn("\r 进度为:%.2f%%" % copy_rate)
if int(copy_rate) >= 100:
break
cp_log.info(
'copy all files complete , files count = {}'.format(all_file_nums))
else:
cp_log.warn('Dir is not exists %s' % dst_path) def bytes2human(n):
symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
prefix = {}
for i, s in enumerate(symbols):
# << 左移” 左移一位表示乘2 即1 << 1=2,二位就表示4 即1 << 2=4,
# 10位就表示1024 即1 << 10=1024 就是2的n次方
prefix[s] = 1 << (i + 1) * 10
for s in reversed(symbols):
if n >= prefix[s]:
value = float(n) / prefix[s]
return '%.1f%s' % (value, s)
return "%sBytes" % n if __name__ == '__main__':
src = 'D://test1'
dst = 'D://copy_thread_test2'
upload_file(src, dst)

  输出结果 

[2018-06-29 15:26:13  - INFO - cp  ] copy file D://test1\20180601\20180601_test.txt complete
进度为:0.61%
[2018-06-29 15:26:13 - INFO - cp ] copy file D://test1\20180602\20180602_test.txt complete
进度为:1.22%
[2018-06-29 15:26:13 - INFO - cp ] copy file D://test1\20180602\教程目录及说明.txt complete
进度为:1.83%
all_file_nums 164
[2018-06-29 15:26:15 - INFO - cp ] copy file D://test1\20180602\MongoDB权威指南(中文版).pdf complete
进度为:2.44%
[2018-06-29 15:26:15 - INFO - cp ] copy file D://test1\ibooks\AIX_HACMP_40pages.pdf complete
进度为:3.05%
……
[2018-06-29 15:29:02 - INFO - cp ] copy file D://test1\Tesseract-OCR\tessdata\tessconfigs\nobatch complete
进度为:99.39%
[2018-06-29 15:29:02 - INFO - cp ] copy file D://test1\Tesseract-OCR\tessdata\tessconfigs\segdemo complete
进度为:100.00%
[2018-06-29 15:29:02 - INFO - cp ] copy all files complete , files count = 164
[2018-06-29 15:29:02 - DEBUG - runtime - time_utils.py - decor- 59 ] func {upload_file} run { 168.7767}s

使用协程批量拷贝文件

#!/usr/bin/env python3
# -*- coding: utf-8 -*- from gevent import monkey;monkey.patch_all()
import os
import shutil
import logging
import time
from functools import wraps
from logging import handlers
from colorama import Fore, Style, init
from multiprocessing.pool import ThreadPool
import queue
import gevent import sys BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR) # 加入环境变量 class Colorlog(object):
"""
记录日志,添加颜色
"""
init(autoreset=True) # 初始化,并且设置颜色设置自动恢复 # 根据信息不同设置不同的颜色格式
info_color = Fore.GREEN + Style.BRIGHT
warn_color = Fore.YELLOW + Style.BRIGHT
debug_color = Fore.MAGENTA + Style.BRIGHT
error_color = Fore.RED + Style.BRIGHT def __init__(self, name):
# 日志格式
log_format = '[%(asctime)s - %(levelname)s - %(name)s ] %(message)s '
self.logger = logging.getLogger(name)
self.logger.setLevel(logging.DEBUG) console_handler = logging.StreamHandler()
# 文件绝对路径
logfile_path = 'test.log' # 每天创建一个日志文件,文件数不超过20个
file_handler = handlers.TimedRotatingFileHandler(
logfile_path, when="D", interval=1, backupCount=20) self.logger.addHandler(console_handler)
self.logger.addHandler(file_handler) file_format = logging.Formatter(fmt=log_format)
console_format = logging.Formatter(
fmt=log_format, datefmt='%Y-%m-%d %H:%M:%S ') console_handler.setFormatter(console_format)
file_handler.setFormatter(file_format) def warn(self, message):
self.logger.warning(Colorlog.warn_color + message) def info(self, message):
self.logger.info(Colorlog.info_color + message) def error(self, message):
self.logger.error(Colorlog.info_color + message) def debug(self, message):
self.logger.debug(Colorlog.info_color + message) cp_log = Colorlog("cp") def run_time(func):
"""
计算程序运行时间的装饰器
:param func:
:return:
""" @wraps(func)
def decor(*args, **kwargs):
start = time.time()
res = func(*args, **kwargs)
end = time.time()
print("func {%s} run {%10.4f}s " % (func.__name__, (end - start)))
return res return decor def copy_file(local_file_path, dst_file_path):
# size = bytes2human(os.path.getsize(local_file_path))
# cp_log.debug(
# 'copy file {} to {}, file size {}'.format(
# local_file_path, dst_file_path, size))
shutil.copy(local_file_path, dst_file_path) # copy file
cp_log.info(
'copy file {} , size= {} complete '.format(
local_file_path, bytes2human(
os.path.getsize(dst_file_path)))) def getdirsize(dir):
"""
获得文件夹中所有文件大小
:param dir:
:return:
"""
size = 0
for root, dirs, files in os.walk(dir):
size += sum([os.path.getsize(os.path.join(root, name))
for name in files])
return bytes2human(size) @run_time
def upload_file(src_path, dst_path):
"""
上传文件
:param src_path:
:param dst_path:
:return:
""" cp_log.info('upload_file %s %s' % (src_path, dst_path))
# 目标目录是否存在,不存在则创建
if not os.path.exists(dst_path):
os.makedirs(dst_path)
cp_log.info('Create Dest Dir %s' % dst_path) tasklist = [] # 任务列表
# 判断是否为目录,存在则把文件拷贝到目标目录下
if os.path.isdir(src_path):
all_file_nums = 0
all_file_size = getdirsize(src_path)
cp_log.info('all_file_size = %s' % all_file_size)
for root, dirs, files in os.walk(src_path):
# 遍历目录下所有文件根,目录下的每一个文件夹(包含它自己),
# 产生3-元组 (dirpath, dirnames, filenames)【文件夹路径, 文件夹名字, 文件名称】
for f in files:
all_file_nums += 1
local_file_path = os.path.join(root, f) # 本地文件路径 如/src/q.txt
dst_file_path = os.path.abspath(
local_file_path.replace(
src_path, dst_path)) # 目标文件路径 如/dst/q.txt
dst_dir = os.path.dirname(dst_file_path) # 目标文件路径文件夹 如/dst/
if not os.path.isdir(dst_dir):
os.makedirs(dst_dir) # 创建目录
cp_log.debug('Create Dest Dir %s' % dst_dir) tasklist.append(
gevent.spawn(
copy_file,
local_file_path,
dst_file_path)) # 开启协程 gevent.joinall(tasklist) # 阻塞等待所有操作都执行完毕 print('all_file_nums ', all_file_nums) cp_log.info(
'copy all files complete , files count = {} , size = {}'.format(all_file_nums, getdirsize(dst_path)))
else:
cp_log.warn('Dir is not exists %s' % dst_path) def bytes2human(n):
symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
prefix = {}
for i, s in enumerate(symbols):
# << 左移” 左移一位表示乘2 即1 << 1=2,二位就表示4 即1 << 2=4,
# 10位就表示1024 即1 << 10=1024 就是2的n次方
prefix[s] = 1 << (i + 1) * 10
for s in reversed(symbols):
if n >= prefix[s]:
value = float(n) / prefix[s]
return '%.1f%s' % (value, s)
return "%sB" % n if __name__ == '__main__':
src = 'C://pythonStudy/python爬虫参考资料'
dst = 'C://pythonStudy/copy_thread_test2'
upload_file(src, dst)

 输出结果 

"C:\Program Files\Python36\python.exe" batch_copy.py
[2018-06-29 22:50:22 - INFO - cp ] upload_file C://pythonStudy/python爬虫参考资料 C://pythonStudy/copy_thread_test2
[2018-06-29 22:50:22 - INFO - cp ] Create Dest Dir C://pythonStudy/copy_thread_test2
[2018-06-29 22:50:22 - INFO - cp ] all_file_size = 620.6M
[2018-06-29 22:50:22 - DEBUG - cp ] Create Dest Dir C:\pythonStudy\copy_thread_test2\python-scraping-master
[2018-06-29 22:50:22 - DEBUG - cp ] Create Dest Dir C:\pythonStudy\copy_thread_test2\python-scraping-master\chapter1
[2018-06-29 22:50:22 - DEBUG - cp ] Create Dest Dir C:\pythonStudy\copy_thread_test2\python-scraping-master\chapter10
[2018-06-29 22:50:22 - DEBUG - cp ] Create Dest Dir ……
[2018-06-29 22:50:23 - INFO - cp ] copy file C://pythonStudy/python爬虫参考资料\python-scraping-master\chapter12\2-seleniumCookies.py , size= 528B complete
[2018-06-29 22:50:23 - INFO - cp ] copy file C://pythonStudy/python爬虫参考资料\python-scraping-master\chapter12\3-honeypotDetection.py , size= 539B complete
[2018-06-29 22:50:23 - INFO - cp ] copy file
[2018-06-29 22:50:24 - INFO - cp ] copy file C://pythonStudy/python爬虫参考资料\python-scraping-master\chapter9\5-BasicAuth.py , size= 229B complete
all_file_nums 130
[2018-06-29 22:50:24 - INFO - cp ] copy file C://pythonStudy/python爬虫参考资料\python-scraping-master\files\test.csv , size= 114B complete
func {upload_file} run { 1.2971}s
[2018-06-29 22:50:24 - INFO - cp ] copy all files complete , files count = 130 , size = 620.6M Process finished with exit code 0

  

 

工具文件

time_utils.py

def run_time(func):
"""
计算程序运行时间的装饰器
:param func:
:return:
"""
@wraps(func)
def decor(*args,**kwargs):
start = time.time()
res = func(*args,**kwargs)
end = time.time()
log.debug("func {%s} run {%10.4f}s " % (func.__name__,(end - start)))
return res return decor

python批量拷贝文件的更多相关文章

  1. python批量进行文件修改操作

    python批量修改文件扩展名 在网上下载了一些文件,因为某种原因,扩展名多了一个后缀'.xxx',手动修改的话因为文件太多,改起来费时费力,于是决定写个小脚本进行修改. 1.要点: import r ...

  2. python 批量创建文件及文件夹(文件夹里再创文件)

    python 批量创建文件及文件夹(文件夹里再创文件)思路:文件建到哪>文件名字叫啥>创建文件夹>去新建的文件下>新建文件>给文件里边写东西>写个反馈给控制台> ...

  3. python之拷贝文件

    做了个小实验, 用于拷贝文件夹下面的jpg. 用于拓展, 可以引入类和方法, 拷贝你指定的任意类型的文件. import os src = 'C:\\Users\\Administrator\\Des ...

  4. python批量json文件转xml文件脚本(附代码)

    场景:在使用了mask rcnn跑实验后标注了大量地json格式文件,现在打算使用yolo和faster rcnn 跑实验 所以需要将之前地json文件转为xml     但是找了很久,没发现有批量处 ...

  5. python批量处理文件夹中文件的问题

    用os模块读取文件夹中文件 原来的代码: import osfrom scipy.misc import imread filenames=os.listdir(r'./unprocess')for ...

  6. python批量修改文件名称

    参考文章:http://www.cnblogs.com/ma6174/archive/2012/05/04/2482378.html 最近遇到一个问题,在网上下载了一批视频课程,需要将每节课的名称标号 ...

  7. python批量删除文件

    敲代码測试时总会碰到要删除日志目录下的日志或者删除一些历史文件.每次都会生成,再測试的时候为了查找错误原因方便总是要在測试前删除这些文件.手动删除比較麻烦.所以写一个批量删除脚本 import os ...

  8. python批量删除文件夹

    制作的python程序跑一次就占200多内存在temp下面,关键是还不释放,最开始都没有发现这个问题,知道自己的c盘越来越小才发现问题所在.所以就有了去删除temp下生成的文件 代码如下: impor ...

  9. python 批量下载文件

    file.txt 的内容为: http://183.xxx.xxx.54:188/my/qqq.ico::qq.exe::0::http://183.xxx.xxx.54:186/my/ddnf.ic ...

随机推荐

  1. idea如何搭建springboot框架

    首先简单介绍下Spring Boot,来自度娘百科:Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进 ...

  2. JavaWeb多文件上传及zip打包下载

    项目中经常会使用到文件上传及下载的功能.本篇文章总结场景在JavaWeb环境下,多文件上传及批量打包下载功能,包括前台及后台部分.  首先明确一点:  无法通过页面的无刷新ajax请求,直接发下载.上 ...

  3. JAVA 面试题及思考

    ==================================== =======学而时习之======================== ===================== 1. p ...

  4. (转)如何最佳地使用memcached?

    转自:http://os.51cto.com/art/201205/335034_all.htm Memcached是由DangaInteractive开发的,高性能的,分布式的内存对象缓存系统,如何 ...

  5. flask + apidoc 生成接口文档(附加一个坑)

    具体使用方法见这里 https://blog.csdn.net/lynnyq/article/details/79254290 挺详细的,我就不抄了. 重点是一个坑: 执行 python manage ...

  6. postman接口功能测试

    前言                                                         之前还没实际做过接口测试的时候呢,对接口测试这个概念比较渺茫,只能靠百度,查看各种 ...

  7. Shell编程-09-Shell中的函数

    目录 基本语法 函数执行 函数示例     函数可以简化程序的代码量,达到更好的代码复用度,因此会让程序变得更加易读.简洁和易修改.其作用就是将需要多次使用的代码整合到一块,使其成为一个整体,然后通过 ...

  8. 你可能不知道的Shell

    Shell也叫做命令行界面,它是*nix操作系统下用户和计算机的交互界面.Shell这个词是指操作系统中提供访问内核服务的程序. 这篇文章向大家介绍Shell一些非广为人知.但却实用有趣的知识,权当品 ...

  9. SCI投稿过程总结、投稿状态解析、拒稿后对策及接受后期相关问答

    SCI投稿过程总结.投稿状态解析.拒稿后对策及接受后期相关问答   http://muchong.com/t-9174366-1 SCI投稿过程总结.投稿状态解析.拒稿后处理对策及接受后期相关问答综合 ...

  10. javascript 减少全部变量

    方法1 自创建一个唯一的全局变量a,把自己用到的变量都加在a上 方法2:模块 String.method('test1', function(){ var a = '12'; return funct ...