看起来python会跟踪read((和readline((的每次运行。它是增量的,每次运行都是增量,最终不会返回任何值。如何找到这个计数器,并随时读取特定的行?
编辑:我的目标是读取一个几Gb大小、数十万行的大文件。如果这是一个迭代器,那么它是不够的,我不想在内存中加载整个文件。如何在不必阅读不必要的行的情况下跳转到特定行?
只有3行的文本文件。
# cat sample.txt
This is a sample text file. This is line 1
This is line 2
This is line 3
# python
Python 3.7.5 (default, Nov 7 2019, 10:50:52)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> file = open('sample.txt', 'r')
>>> file.readline()
'This is a sample text file. This is line 1n'
>>> file.readline()
'This is line 2n'
>>> file.readline()
'This is line 3n'
>>> file.readline()
''
>>> file.readline()
''
>>> file.read()
''
>>> file.read(0)
''
>>> file.read()
''
>>>
# python
Python 3.7.5 (default, Nov 7 2019, 10:50:52)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> file = open('sample.txt', 'r')
>>> file.read()
'This is a sample text file. This is line 1nThis is line 2nThis is line 3n'
>>> file.read()
''
>>> file.readline()
''
>>>
Python中的文件对象是一个迭代器,在文件中的不同行上迭代。您可以使用readlines()
一次将所有(剩余(行读取到列表中,或者使用read()
读取文件中的单个或全部(剩余(字符(默认值为all,使用一个参数表示要读取的字符数(,但默认行为(如果直接迭代文件(与readline
相同,即从文件中生成下一行。
您可以将其与enumerate
组合,以获得另一个迭代器,该迭代器生成每一行的行号(除非您指定了enumerate
的start
参数,否则第一行的行号为0
(,或者获得特定的行:
>>> f = open("test.txt")
>>> lines = enumerate(f)
>>> next(lines)
(0, 'first linen')
>>> next(lines)
(1, 'second linen')
>>> next(lines)
(2, 'third linen')
>>> f = open("test.txt")
>>> lines = enumerate(f)
>>> next(l for i, l in lines if i == 3)
'fourth linen'
还有seek
方法,它可以用来跳转到文件中的特定字符,这对于将文件"重置"到第一个位置(或者重新打开它(很有用,但除非你知道每一行的确切长度,否则对查找特定行没有多大帮助。(见下文(
如果您想"按任何顺序读取任何行",最简单的方法是使用readlines
将所有行实际读取到列表中,然后访问该列表中的项目(前提是您的文件不太大(。
>>> f = open("test.txt")
>>> lines = f.readlines()
>>> lines[3]
'fourth linen'
>>> lines[1]
'second linen'
我的目标是读取一个几Gb大小、数十万行的大文件。
由于Python知道一行的结束位置以及特定行的开始位置的唯一方法是计算它遇到的n
字符数,因此无法读取整个文件。如果文件很大,并且必须按顺序重复读取行,则一次读取文件一次,将每行的起始位置存储在字典中可能是有意义的。之后,您可以使用seek
快速跳转到特定行,然后读取该行。
f = open("test.txt")
total = 1
lines = {}
for i, line in enumerate(f):
lines[i] = total - 1
total += len(line)
# jump to and read individual lines
f.seek(lines[3])
print(f.readline())
f.seek(lines[0])
print(f.readline())
当使用readline()
时,文件对象(即来自open(file)
(表现为迭代器。本身没有计数器。如果用file.__next__()
代替file.readline()
,可以观察到这一点。
如果你不介意一次读取整个文件,简单的解决方案就是创建一个所有行的列表,然后引用你感兴趣的行,作为
lines=file.readlines() # this is a list