001 Python之文件夹归并算法(实战17亿数据有序合并没问题,单线程)

来源:互联网 发布:英雄联盟mac版打不开 编辑:程序博客网 时间:2024/06/05 02:05

Python之文件夹归并算法

1. github项目地址

github项目地址

2. 项目介绍

第一步:创建数据

  1. 首先打开CreateData模块,运行下该模块,你就能在本项目路径下的data下拿到生成的数据,用这个模拟文件夹归并
  2. 其次CreateData模块生成了50个文件,总共579M数据,文件夹内文件越多,本项目的优势越能体现出来
  3. 运行下Merge模块,然后两分钟五十三秒左右,你就能拿到579M数据组成的一个排好序的大文件,本项目经过了17亿级别的数据测试,没有丢失数据以及其他情况
创造数据代码
import os, time, randomclass 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.__insertAndSort(list1, [nowFile, [nowLine, nowLine.split("\t")[0]]])  # 插入排序,节省排序时间                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

第三步:测试结果(文件越多,二分法插入排序的优势越大)

二分法插入归并测试  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

总结

在你进行多文件合并的时候,很多时候你需要大量的两两合并对文件进行有序归并,本项目就是为了解决文件夹文件归并而出现的(前提是你文件夹中每个文件必须有序)。
原创粉丝点击