最近学习python系统编程,学习到mmap:
内存映射(mmap)文件对象的行为既像bytearray 又像文件对象。你可以在大部分接受bytearray 的地 方使用mmap对象;例如,你可以使用re 模块来搜索一个内存映射文件。你也可以通过执行 obj[index] = 97 来修改单个字节,或者通过对切片赋值来修改一个子序列: obj[i1:i2] = b'...'。你还可以在文 件的当前位置开始读取和写入数据,并使用 seek() 前往另一个位置。
mmap对象对文件操作应该非常快,所以写了个程序测试了一下,果然效果非常好,大家可以参考一下,可能以后能用的上这个对象;
代码如下:
import mmap
import os
import multiprocessing as mp
import concurrent.futures as TPE
import argparse
global mms ,mmd
def datacopy(pos): #文件复制函数;
mmd.seek(pos[0])
mmd.write(mms[pos[0]:pos[1]])
if __name__ == "__main__" :
import time
print("task begin at time {}".format(time.strftime('%X')))
parse = argparse.ArgumentParser()
parse.add_argument("-n","--count",default="",dest="count",
help="threadnum",type=int)
parse.add_argument("-f", "--filename", default="", dest="file",
help="source filename", type=str)
args = parse.parse_args()
tn = args.count #文件分成几块,有多个线程操作复制;
filename = args.file
print(filename)
import os.path as op
filenamedes = op.basename(filename)
filenamedes = filenamedes.replace(".","_copy.")
f=open(filename,"r+b")
mms = mmap.mmap(f.fileno(),0) #mmap对象生成
size = mms.size() #取文件大小
with open(filenamedes, 'w+b') as fs:
pass
fs = open(filenamedes,"r+b")
mmd = mmap.mmap(fs.fileno(),size) #生产目标对象
part_size = int(size/tn)
print(part_size,tn,size)
pos_list =[]
for i in range(0,tn): #计算每块操作大小
if i == tn - 1 :
pos_list.append([i*part_size,size])
else:
pos_list.append([i*(part_size),(i+1)*part_size])
print(pos_list)
with TPE.ThreadPoolExecutor(max_workers = tn) as excutor: #线程池 执行每块复制任务
future = excutor.map(datacopy,pos_list)
mmd.close()
mms.close() #关闭对象
fs.close()
f.close()
print("task end at time {}".format(time.strftime('%X')))