Python之文件夹归并算法
1. github项目地址
github项目地址
2. 项目介绍
第一步:创建数据
- 首先打开CreateData模块,运行下该模块,你就能在本项目路径下的data下拿到生成的数据,用这个模拟文件夹归并
- 其次CreateData模块生成了50个文件,总共579M数据,文件夹内文件越多,本项目的优势越能体现出来
- 运行下Merge模块,然后两分钟五十三秒左右,你就能拿到579M数据组成的一个排好序的大文件,本项目经过了17亿级别的数据测试,没有丢失数据以及其他情况
创造数据代码
import os, time, random
class CreateData:
def __init__(self, fileDir, fileCount):
self.fileDir = fileDir
self.fileCount = fileCount
def createData(self):
for i in range(self.fileCount):
file = open(os.path.join(self.fileDir, "Data-%s.txt" % str(i + 1).zfill(2)), "w", encoding="utf-8",
errors="strict")
for data in range(random.randrange(10), 5000000, 7):
writeStr = str(data).zfill(7) + "\t" + str(data).zfill(7) + "\n"
file.write(writeStr)
data = CreateData(r"data", 50)
data.createData()
整体算法代码
import time, os
'''
create by Luo 2017-7-22 14:53:21
'''
class Merge:
def __init__(self, orginDir, objectPath):
self.fileNameList = os.listdir(orginDir)
self.fileList = []
self.objectFile = open(objectPath, "w", -1, encoding="utf-8", errors="strict")
for fileName in self.fileNameList:
file = open(os.path.join(orginDir, fileName), "r", -1, encoding="utf-8", errors="strict")
self.fileList.append(file)
def mergeFile(self):
print("开始文件夹合并:", time.ctime())
list1 = []
for file in self.fileList:
line = file.readline()
if line:
list1.append([file, [line, line.split("\t")[0]]])
else:
file.close()
self.fileList.remove(file)
list1.sort(key=lambda x: x[1][1])
while len(list1) != 0:
self.objectFile.write(list1[0][1][0])
nowFile = list1[0][0]
nowLine = nowFile.readline()
list1.remove(list1[0])
if nowLine:
self.__helfInsert(list1, [nowFile, [nowLine, nowLine.split("\t")[0]]])
else:
nowFile.close()
print("结束文件夹合并:", time.ctime())
def __insertAndSort(self, list1, listItem):
for index in range(len(list1)):
if listItem[1][1] <= list1[index][1][1]:
list1.insert(index, listItem)
break
else:
list1.append(listItem)
def __helfInsert(self, list1, listItem):
num1 = listItem[1][1]
low = 0
length = len(list1)
high = length - 1
while low <= high:
mid = (low + high) // 2
if num1 < list1[mid][1][1]:
high = mid - 1
elif num1 > list1[mid][1][1]:
low = mid + 1
else:
list1.insert(mid, listItem)
break
else:
if low == length:
list1.append(listItem)
else:
list1.insert(low, listItem)
def __del__(self):
self.objectFile.close()
orginDir = r"data"
objectPath = r"DirMergeSort.txt"
merge1 = Merge(orginDir, objectPath)
merge1.mergeFile()
第三步:测试结果(文件越多,二分法插入排序的优势越大)
二分法插入归并测试 50个文件 579M 耗时 0:02:53
开始文件夹合并: Sat Jul 22 09:00:14 2017
结束文件夹合并: Sat Jul 22 09:03:07 2017
插入排序归并测试 50个文件 579M 耗时 0:06:47
开始文件夹合并: Sat Jul 22 09:04:19 2017
结束文件夹合并: Sat Jul 22 09:11:06 2017
总结
在你进行多文件合并的时候,很多时候你需要大量的两两合并对文件进行有序归并,本项目就是为了解决文件夹文件归并而出现的(前提是你文件夹中每个文件必须有序)。