如何在python中拆分一个巨大的文本文件

qua*_*ana 23 python text-files

我有一个巨大的文本文件(~1GB),遗憾的是我使用的文本编辑器不会读取如此大的文件.但是,如果我可以将它分成两个或三个部分,我会没事的,所以,作为一个练习,我想在python中编写一个程序来完成它.

我认为我希望程序要做的是找到一个文件的大小,将该数字分成几部分,对于每个部分,以块的形式读取到该点,写入文件名 .nnn输出文件,然后读取 -到下一个换行符并写入,然后关闭输出文件等.显然,最后一个输出文件只是复制到输入文件的末尾.

你能帮我解决关键文件系统相关的部分:文件大小,读取和写入块以及读取换行符吗?

我将首先编写这个代码测试,所以没有必要给我一个完整的答案,除非它是一个单行;-)

Jam*_*mes 35

linux有一个split命令

split -l 100000 file.txt

会分成等于100,000行大小的文件


Kam*_*iel 15

检查os.stat()文件大小和file.readlines([sizehint]).这两个函数应该是阅读部分所需要的,希望你知道如何写作:)

  • `os.path.getsize(filename)`有什么问题? (5认同)

Ale*_*x L 9

作为替代方法,使用日志库:

>>> import logging.handlers
>>> log = logging.getLogger()
>>> fh = logging.handlers.RotatingFileHandler("D://filename.txt", 
     maxBytes=2**20*100, backupCount=100) 
# 100 MB each, up to a maximum of 100 files
>>> log.addHandler(fh)
>>> log.setLevel(logging.INFO)
>>> f = open("D://biglog.txt")
>>> while True:
...     log.info(f.readline().strip())
Run Code Online (Sandbox Code Playgroud)

您的文件将显示如下:

filename.txt(文件结尾)
filename.txt.1
filename.txt.2
...
filename.txt.10(文件开头)

这是一种快速简便的方法,可以使大型日志文件与您的RotatingFileHandler实现相匹配.


Ram*_*Ram 9

现在,有一个 pypi 模块可用于将任何大小的文件拆分为块。看一下这个

https://pypi.org/project/filesplit/


Joe*_*erg 6

不要忘记seek()mmap()用于随机访问文件。

def getSomeChunk(filename, start, len):
    fobj = open(filename, 'r+b')
    m = mmap.mmap(fobj.fileno(), 0)
    return m[start:start+len]
Run Code Online (Sandbox Code Playgroud)


ins*_*get 6

虽然Ryan Ginstrom 的答案是正确的,但确实需要比应有的时间更长的时间(正如他已经指出的)。itertools.islice这是通过连续迭代打开的文件描述符来避免多次调用的方法:

def splitfile(infilepath, chunksize):
    fname, ext = infilepath.rsplit('.',1)
    i = 0
    written = False
    with open(infilepath) as infile:
        while True:
            outfilepath = "{}{}.{}".format(fname, i, ext)
            with open(outfilepath, 'w') as outfile:
                for line in (infile.readline() for _ in range(chunksize)):
                    outfile.write(line)
                written = bool(line)
            if not written:
                break
            i += 1
Run Code Online (Sandbox Code Playgroud)


Rya*_*rom 5

这种生成器方法是一种(慢)方式来获取一条线而不会炸毁你的记忆.

import itertools

def slicefile(filename, start, end):
    lines = open(filename)
    return itertools.islice(lines, start, end)

out = open("/blah.txt", "w")
for line in slicefile("/python27/readme.txt", 10, 15):
    out.write(line)
Run Code Online (Sandbox Code Playgroud)