无法从CPython读取大量(20GB)文件

时间:2013-11-07 19:08:01

标签: python file io

我有一些我无法理解的CPython问题。这一切都归结为使用相同的代码来读取小文本文件但无法读取20GB txt文件中的单行这一事实。

一些有用的信息:

  • 较小的文件~1MB是20GB大文件的一个子集(从一开始就是1MB)
  • 这两个文件都是文本文件,其行宽为~2000chars,由CR(\ r)
  • 分隔

显而易见的解决方案:

f = open(r'filename', 'r')
for line in f:
    print(line)
f.close()

有效......但是......仅供短文件使用。因为大的人会永远挂起(或者至少应该打印至少第一行)。

所以我想至少尝试读一行如下:

f = open(r'filename', 'r')
print(f.readline())
f.close()

这里的类似情况 - 适用于小文件,但是对于大文件,经过大量时间吐出该消息:

Traceback (most recent call last):
  File "***", line 16, in <module>
    print(f.readline())
SystemError: ..\Objects\stringobject.c:3902: bad argument to internal function

我应该如何读取大文本文件?

更新

原来人类认为更清楚,有足够的睡眠;-)。问题解决了 - 结果我忽略了文档中的一句话:

  

Python通常使用通用换行符支持构建; 提供'U'将文件作为文本文件打开,但行可以通过以下任何一种终止:Unix行尾约定'\ n',Macintosh约定'\ r' ,或Windows约定'\ r \ n'。

默认情况下,通用换行符被“打开”。

我的上述陈述:

print(f.readline())

只读了一行部分 false(我的不好)。记得我说我的小文件是通过大块的大块创建的吗?在那个操作过程中,行结束从(CR)变为(CRLF),所以我看到的是第一行。所有这一切让我觉得这个问题不在线上。

谢谢大家的时间和帮助。

2 个答案:

答案 0 :(得分:5)

虽然你的测试&#34;只打印一行,这并不意味着它只从文件中读取一行。对于我在\r分隔的测试文件中,我也只得到一行输出。但是,如果我使用for循环读取每一行,仍然只打印一行。或者,如果我在多行文件上再次尝试readline(),它就不会再提供任何行。

尝试使用同一文件中的'rU'参数打开文件:

f =  open('filename', 'rU')

我对包含多行\r分隔文本的文件的测试给出了:

f = open('test.txt','r')  # Opening the "wrong" way
for line in f:
    print line

输出:

abcdef

然后使用rU

f = open('test.txt','rU')
for line in f:
    print line

输出:

abcdef

abcdef

abcdef

abcdef

abcdef

编辑:为了支持Joran的解释,此测试几乎表明整个文件正在加载并且回车字符导致过度打印只看到一行输出...

f = open('test.txt','r')     #  Opening the "wrong" way again
for line in f:
    print "XXX{}YYY".format(line)

输出被覆盖......

YYYdefdef

答案 1 :(得分:0)

def my_readline(fh,delim):
    return "".join(iter(lambda:fh.read(1),delim))

f = open(some_file)
line = my_readline(f,"\r")

应该可以工作,如果你至少可以.read(1)工作...但如果这不起作用我不知道任何事情......可能使用shell命令将文件拆分成较小的块...但我怀疑beroe的答案是真正的答案