正在打开一个25GB的文本文件进行处理



我有一个25GB的文件需要处理。以下是我目前正在做的事情,但打开需要非常长的时间:

collection_pricing = os.path.join(pricing_directory, 'collection_price')
with open(collection_pricing, 'r') as f:
    collection_contents = f.readlines()
length_of_file = len(collection_contents)
for num, line in enumerate(collection_contents):
    print '%s / %s' % (num+1, length_of_file)
    cursor.execute(...)

我该如何改进?

  1. 除非文件中的行真的很大,否则不要在每一行都打印进度。打印到终端的速度非常慢。打印进度,例如每100行或每1000行。

  2. 使用可用的操作系统工具来获取文件的大小-os.path.getsize(),请参阅在Python中获取文件大小?

  3. 去掉readlines()以避免向内存中读取25GB。相反,逐行读取和处理,请参阅例如如何在python 中逐行读取大文件

将文件传递两次:一次用于计数行,一次用于打印。永远不要对这么大的文件调用readlines——您最终会将所有内容都交换到磁盘上。(实际上,一般情况下永远不要调用readlines。这很傻。)

(顺便说一句,我假设你实际上是在使用行数,而不仅仅是行数——你在那里发布的代码实际上除了文件中的换行数之外,没有使用文件中的任何内容。)

结合上面的答案,下面是我如何修改它的。

size_of_file = os.path.getsize(collection_pricing)
progress = 0
line_count = 0
with open(collection_pricing, 'r') as f:
    for line in f:
        line_count += 1  
        progress += len(line)
        if line_count % 10000 == 0:
            print '%s / %s' % (progress, size_of_file)

这有以下改进:

  • 不使用readlines(),因此不将所有内容存储到内存中
  • 每10000行仅打印一次
  • 使用文件大小而不是行数来衡量进度,所以不必迭代文件两次

最新更新