使用python解析大型(20GB)文本文件 - 以2行读取1

Jam*_*mes 15 python large-files

我正在解析一个20Gb的文件,并将符合某种条件的行输出到另一个文件,但偶尔python会同时读取2行并连接它们.

inputFileHandle = open(inputFileName, 'r')

row = 0

for line in inputFileHandle:
    row =  row + 1
    if line_meets_condition:
        outputFileHandle.write(line)
    else:
        lstIgnoredRows.append(row)
Run Code Online (Sandbox Code Playgroud)

我检查了源文件中的行结尾,并将它们检出为换行符(ascii char 10).拉出问题行并在隔离中解析它们按预期工作.我在这里遇到一些python限制吗?第一个异常文件中的位置大约是4GB标记.

Jos*_*ton 23

快速谷歌搜索"大于4gb的python阅读文件"产生了许多结果.在这里 看到这样一个例子和另一个从第一个接管的例子.

这是Python中的一个错误.

现在,解释这个bug; 重现并不容易,因为它取决于内部FILE缓冲区大小和传递给fread()的字符数.在Microsoft CRT源代码中,在open.c中,有一个块从这个令人鼓舞的评论开始"这是困难的部分.我们在缓冲区末尾发现了一个CR.我们必须先看看下一个char是否是LF. " 奇怪的是,在Perl源代码中有一个几乎完全相同的函数副本:http://perl5.git.perl.org/perl.git/blob/4342f4d6df6a7dfa22a470aa21e54a5622c009f3 : /win32/win32.c#l3668 问题在于调用到SetFilePointer(),用于在前瞻后退一个位置; 它会失败,因为它无法以32位DWORD返回当前位置.[修复很容易; 你看到了吗?]此时,函数认为下一个read()将返回LF,但它不会因为文件指针没有被移回.

解决方法:

但请注意,Python 3.x不受影响(原始文件始终以二进制模式打开,CRLF转换由Python完成); 使用2.7,您可以使用io.open().


Ray*_*ger 7

4GB标记可疑地接近可以存储在32位寄存器(2**32)中的最大值.

您发布的代码本身看起来很好,所以我怀疑您的Python构建中存在错误.

FWIW,如果使用枚举,代码片段会更清晰:

inputFileHandle = open(inputFileName, 'r')

for row, line in enumerate(inputFileHandle):
    if line_meets_condition:
        outputFileHandle.write(line)
    else:
        lstIgnoredRows.append(row)
Run Code Online (Sandbox Code Playgroud)