python批量拷贝文件
普通批量拷贝文件
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批量拷贝文件的更多相关文章
- python批量进行文件修改操作
python批量修改文件扩展名 在网上下载了一些文件,因为某种原因,扩展名多了一个后缀'.xxx',手动修改的话因为文件太多,改起来费时费力,于是决定写个小脚本进行修改. 1.要点: import r ...
- python 批量创建文件及文件夹(文件夹里再创文件)
python 批量创建文件及文件夹(文件夹里再创文件)思路:文件建到哪>文件名字叫啥>创建文件夹>去新建的文件下>新建文件>给文件里边写东西>写个反馈给控制台> ...
- python之拷贝文件
做了个小实验, 用于拷贝文件夹下面的jpg. 用于拓展, 可以引入类和方法, 拷贝你指定的任意类型的文件. import os src = 'C:\\Users\\Administrator\\Des ...
- python批量json文件转xml文件脚本(附代码)
场景:在使用了mask rcnn跑实验后标注了大量地json格式文件,现在打算使用yolo和faster rcnn 跑实验 所以需要将之前地json文件转为xml 但是找了很久,没发现有批量处 ...
- python批量处理文件夹中文件的问题
用os模块读取文件夹中文件 原来的代码: import osfrom scipy.misc import imread filenames=os.listdir(r'./unprocess')for ...
- python批量修改文件名称
参考文章:http://www.cnblogs.com/ma6174/archive/2012/05/04/2482378.html 最近遇到一个问题,在网上下载了一批视频课程,需要将每节课的名称标号 ...
- python批量删除文件
敲代码測试时总会碰到要删除日志目录下的日志或者删除一些历史文件.每次都会生成,再測试的时候为了查找错误原因方便总是要在測试前删除这些文件.手动删除比較麻烦.所以写一个批量删除脚本 import os ...
- python批量删除文件夹
制作的python程序跑一次就占200多内存在temp下面,关键是还不释放,最开始都没有发现这个问题,知道自己的c盘越来越小才发现问题所在.所以就有了去删除temp下生成的文件 代码如下: impor ...
- python 批量下载文件
file.txt 的内容为: http://183.xxx.xxx.54:188/my/qqq.ico::qq.exe::0::http://183.xxx.xxx.54:186/my/ddnf.ic ...
随机推荐
- zend studio导入外部项目乱码怎么解决
在zendstudio ide中,导入一个工程后,发现工程里面很多的文件都打上了红色的叉叉,打开这些文件一看,发现只要是有汉字存在的文件,都出现了乱码.按住alt+enter发现,该文件的编码默认为g ...
- poj-2406(字符串hash)
题目链接:传送门 思路:字符串hash,终止条件竟然判断错了,真是太大意了. #include<iostream> #include<cstdio> #include<c ...
- springboot深入学习(三)-----docker
一.spring data思路 spring data使用统一的api来对各种数据库存储技术进行数据访问操作提供了支持,包括oracle.mysql.redis.mongoDB等等.主要是通过spri ...
- boost-使用说明
1. boost库中大部分组件不需要编译,直接包含对应头文件即可使用,如#include "boost/array.hpp",因为组件的声明和实现都包含在头文件hpp中. 其它一些 ...
- 程序重复报more than 'max_user_connections' active connections问题解决
早晨,开发扔过来一个问题,截图如下: ums already has more than 'max_user_connections' active connections 查看数据库发现: 最大连接 ...
- ID、句柄、指针、对象互相转换
/*************************************************************************************************** ...
- java基础-day26
第03天 java基础加强 今日内容介绍 u BeanUtils概述及使用 u XML简介及约束 u XML解析 第1章 XML简介 1.1 XML基本语法 1.1.1 XML概述 XML全称为 ...
- VS SVN
AnkhSVN - Subversion Support for Visual Studio 直接包管理中就可以安装 VS2015和SVN合作 Visual Studio 添加SVN插件 Ank ...
- python标准库及其它应用
一: sys模块的介绍: 程序如下: #coding:utf-8import sysprint sys.argv[0]print sys.argv[1]print sys.argv[2] 打开cmd窗 ...
- LCA tarjan+并查集POJ1470
LCA tarjan+并查集POJ1470 https://www.cnblogs.com/JVxie/p/4854719.html 不错的一篇博客啊,让我觉得LCA这么高大上的算法不是很难啊,嘻嘻嘻 ...