在python中读取非常大的文本文件会正确迭代

时间:2015-11-24 19:40:55

标签: python

我有一个1.4GB的文件,我试图迭代每一行,我尝试了正常的方法,这发生了:

textfile = open("myfile.txt") 
while True:
    line = text_file.readline()
    if not line: break
    counter+=1
print counter

好的,一切看起来都不错,但后来我意识到计数低于应有的数量,所以我写了这个:

counter=0
total_lines = 0
while True:
    line = text_file.readline()
    total_lines+=1
    if target in line:
        print line.split("|")[0].strip(), counter, total_lines
        counter+=1

相同数量的行,但我知道这个文件有超过2000万行的事实,谁知道我做错了什么?

编辑:似乎人们怀疑我是否正在阅读正确的文件,我如何验证行等等。

如果我运行这个只是一个简单的例子:

HAIRY MOOSE 0 4722388
HAIRY MOOSE 1 4722389
HAIRY MOOSE 2 4722390
....
....
IN *HAIRY MOOSES CLEANING 45 12244264
IN *HAIRY MOOSES OF TU 46 12244265
IN *HAIRY MOOSES OF TULSA 47 12244266

这是我的输出:

{{1}}

但是如果我以另一种方式阅读它,它会在找到一个匹配之前完成。

2 个答案:

答案 0 :(得分:2)

以您的方式迭代文件没有任何本质上的错误。我已经打开了更大的文件并以同样的方式走了它们; there is no size limit on files in python

可能的解释:

  • 您的文件不是换行符。无论你用什么来计算线条的描述都不同于python。
  • 对文件进行某种并发修改。在此之前,您是否在编辑代码中的文件?另一个程序是否动态编辑该文件?在地面实况检查和运行时之间是否有可能改变文件?

检查方法:

  • 手动检查(最后)行打印出行(或者可能只是最后一行)。如果它与文本文件中的最后一行相同,那么问题可能不是资源被修改。

  • 尝试手动拆分使用read()代替readline(),然后手动拆分并逐步完成。如果len(myfile.read().split('\n'))没有给出正确的答案,len(myfile.read().split('\r')),则可能是delineation problem。也许这两个总和你正在寻找的数字?

  • 检查线路长度,直到找到错误的线路这些线路是否应该长线?在您独立的事实检查地面实况机器中,您是积极的,生成一个行长度计数。然后逐步完成并验证每行是否与Python中的行一样长。如果我的数学成立,则不可能是(1)每一行都是正确的长度和(2)两个文件中的字符总数相同(顺便说一下:验证),但(3)你没有考虑正确的行数。取第一行不正确的长度并手动检查。什么令人困惑的python(再次,我期待一个描述问题)

  • 根据文件类型更改read mode

  

默认设置是使用文本模式,可以将'\ n'字符转换为   写作和回读时的平台特定表示。   因此,打开二进制文件时,应将'b'附加到模式   以二进制模式打开文件的值,这将提高可移植性。   (附加'b'即使在不处理二进制和   文本文件不同,它用作文档。)见下文   更多可能的模式值

  • 仔细检查你的基本事实......你确定你需要这样做吗?我希望你已经验证了你的基本事实。 (对于我的独立行数,我很少会“积极”)。它是一个数字文件吗?也许你可以使用numpy.loadtxt。你能用pandas吗?它是一个数据库吗?如果它是.mat文件中的矩阵,那么scipy.loadmat可能会有用。巨大的数据很少随机格式化,大多数有用的格式人已经做得很好,所以手动解析一个长文件可能不是你最好的选择,在这种情况下,一些神秘的更有趣不是解决。

答案 1 :(得分:0)

不同的操作系统有different sense构成'线'的内容

视窗:

line\r\n

Unix和OS X

line\n

Python支持Universal Newline,它将支持两个行结尾。试试吧。

演示:

from __future__ import print_function

import os 

les={'Unix':chr(10), 'MacOS':chr(13), 'Windows': ''.join([chr(13), chr(10)])}

n=10000
for osn, le in les.items():
   fn='{} {} lines.txt'.format(osn, n)
   print(fn)
   with open(fn, 'wb') as f:
       for x in range(n):
           f.write('line {}{}'.format(x, le))

   for mode in ('r', 'rb', 'rU'):
       with open(fn, mode) as f:
           print("{:10d} lines with {}".format(sum(1 for _ in f), mode))

   os.remove(fn)    

在Unix上,Windows打印:

Windows 10000 lines.txt
     10000 lines with r
     10000 lines with rb
     10000 lines with rU
Unix 10000 lines.txt
     10000 lines with r
     10000 lines with rb
     10000 lines with rU
MacOS 10000 lines.txt
         1 lines with r
         1 lines with rb
     10000 lines with rU

在Windows上,如果您将文件置于文本模式(使用with open(fn, 'w') as f:),它将会使换行符加倍。