大文件检索-Python

需求:有一个1,500,000行数据的文件,需要进行多次检索。其中每行文件为一个列表,且每行列表的首位有序

问题:使用一般的循环检索方式,非常耗时,检索速度慢。

一、基础语法

      1、拆分文件的路径和文件名

      如要获取的文件绝对路径为:/aaa/aaa.txt,方法如下:

import os

filePath = "/aaa/aaa.txt"
array=os.path.split(filePath)
#得到的array由两部分组成,文件路径和文件名
print "array[0]:\n",array[0]
print "array[1]:\n",array[1]
'''
结果为:
array[0]:
/aaa
array[1]:
aaa.txt
'''

或者用下面的方法:

(filePath,fileName) = os.path.split(fileOriginPath)

2、拆分文件名主文件名和扩展名

(mainName,extension) = os.path.splitext(filePath)
print "mainName:\n",mainName
print "extension:\n",extension
'''
结果是:
mainName:
aaa
extension:
.txt
'''

二、大文件拆分

由于需求中文件行数过多,故考虑将文件进行拆分。

每100,000行为分割线,进行文件拆分。

话不多说,上代码

import os

#拆分大文件   100,000为分割
def getFilesFromOneFile(fileOriginName):
    fileName = os.path.split(fileOriginName)[1]
    mainName = os.path.splitext(fileName)[0]
    target_dir = '/xxx/xxx/test/split_temp/'
    #计数器
    flag = 0
    #文件名,用来生成以name为主文件名结尾的文件,区分每个分割文件
    name = 0
    #存放数据
    dataList = []
    with open(filename,'r') as f:
        for line in f:
           flag+=1
           dataList.append(line)
           if flag == 100000:
                targetFile = target_dir+filename1+str(name)+".txt"
                with open(targetFile,"w+") as f_target:
                    for data in dataList:
                        f_target.write(data)
                    name+=1
                    flag=0
                    dataList=[]

    #处理最后一批行数少于100,000行的
    rouNum = 0 #用于计算最后一个文件总行数
    with open(target_dir+filename1+str(name)+".txt","w+") as f_target:
        for data in dataList:
           f_target.write(data)
           rouNum += 1
    pre_path=target_dir+fileName
    fileNum=name
    returnData.append(pre_path)#返回预设路径
    returnData.append(fileNum)#返回最后文件的name
    returnData.append(rowNum)#返回最后一个文件的总行数
    return returnData

三、二分查找算法

拆分完文件后,再循环检索还是很浪费时间。好在文件的首列是有序的。故定位到分割文件后,再用二分查找算法进行检索。

例如,在文件中搜索首列为x所在行的内容:


#二分检索
def bin_search(data_set,val,rowNum):
    #low和hign代表 最小下标,最大下标
    low = 0
    high = rowNum-1
    while(low<=high):
        mid=(low+high)//2
        if data_set[mid]==val:
           return mid
        elif data_set[mid][0]>val:
           high=mid-1
        else:
           low=mid+1
    return #return null代表没找到

四、Main方法如下:

def readFile(fileName,index):
    #根据索引,读取文件的指定行
    with open(filename,'r') as f:
        for line in f.readlines():
            if line[0]==index:
                return line
    return   

if "__name__"=="__main__":
    file = "/aaa/aaa.txt" #file为含1,460,000行,每行三列数据的文件
    returnData = getFilesFromOneFile(file)#将文件拆分成15个子文件
    prePath = returnData[0]
    fileNum = returnData[1]
    lastRowNum = returnData[2]
    fileIndex = x%100000
    if fileIndex 

结束啦~~~~

你可能感兴趣的:(python)