2

我有一些我无法理解的 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())

只读了一行是部分错误的(我的错)。还记得我说过我的小文件是通过大文件的一部分创建的吗?在那次操作中,行尾从(CR)变为(CRLF),所以我看到的是第一行。所有这些让我认为问题不在行尾。

谢谢大家的时间和帮助。

4

2 回答 2

5

尽管您的“测试”仅打印一行,但这并不意味着它仅从文件中读取一行。对我来说,在\r-delimited 测试文件中,我也只能得到一行输出。但是,如果我使用for循环读取每一行,它仍然只打印一行。或者,如果我readline()在多行文件上再次尝试,它不会再提供任何行。

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

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

我对带有多行\r-delimited 文本的文件的测试给出:

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
于 2013-11-07T19:32:23.347 回答
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的答案是真实的回答

于 2013-11-07T19:32:10.947 回答