处理超过30GB大文本文件的最佳方法及进度显示

4 投票
3 回答
910 浏览
提问于 2025-04-16 18:25

[新手问题]

大家好,

我正在处理一个超过30GB的大文本文件。

我需要对每一行进行一些处理,然后以JSON格式写入数据库。当我读取文件并用“for”循环处理时,我的电脑在处理大约10%的数据后就崩溃了,显示蓝屏。

我现在使用的是:

f = open(file_path,'r')
for one_line in f.readlines():
    do_some_processing(one_line)
f.close()

另外,我该如何显示到目前为止处理了多少数据的整体进度呢?

非常感谢大家。

3 个回答

0

使用readline这个方法需要你找到文件中每一行的结束。如果某些行特别长,可能会导致你的程序崩溃(因为内存不够用来存储整行内容)。

为了显示进度,你可以先检查一下文件的大小,比如可以用下面的方式:

import os
f = open(file_path, 'r')
fsize = os.fstat(f).st_size

然后,你的任务进度可以通过处理的字节数除以文件大小,再乘以100,得到一个百分比。

1

我用一个类似的函数来解决问题。你可以用它来处理任何可以迭代的东西。

把这个改成

for one_line in f.readlines():

你只需要把你的代码改成

# don't use readlines, it creates a big list of all data in memory rather than
# iterating one line at a time.
for one_line in in progress_meter(f, 10000):

你可能想选择一个更小或更大的值,这取决于你想花多少时间来打印状态信息。

def progress_meter(iterable, chunksize):
    """ Prints progress through iterable at chunksize intervals."""
    scan_start = time.time()
    since_last = time.time()
    for idx, val in enumerate(iterable):
        if idx % chunksize == 0 and idx > 0: 
            print idx
            print 'avg rate', idx / (time.time() - scan_start)
            print 'inst rate', chunksize / (time.time() - since_last)
            since_last = time.time()
            print
        yield val
5

文件句柄是可以进行迭代的,使用上下文管理器会更好。你可以试试这个:

with open(file_path, 'r') as fh:
  for line in fh:
    process(line)

这样做可能就足够了。

撰写回答