Python文件read()和readline()计数器?

omvjsjqw  于 2023-01-22  发布在  Python
关注(0)|答案(2)|浏览(83)

看起来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 1\n'
>>> file.readline()
'This is line 2\n'
>>> file.readline()
'This is line 3\n'
>>> 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 1\nThis is line 2\nThis is line 3\n'
>>> file.read()
''
>>> file.readline()
''
>>>
gwbalxhn

gwbalxhn1#

Python中的file对象是一个迭代器,迭代文件中的不同行。(剩余)行一次写入列表,或read()读取单个或全部文件中的(剩余)个字符(默认值为all,使用参数表示要读取的字符数),但是默认行为(如果直接迭代文件)与readline相同,即从文件中产生下一行。
你可以把它和enumerate结合起来,得到另一个迭代器,生成每一行沿着行号(第一行的行号是0,除非你指定了enumeratestart参数),或者得到一个特定的行:

>>> f = open("test.txt")
>>> lines = enumerate(f)
>>> next(lines)
(0, 'first line\n')
>>> next(lines)
(1, 'second line\n')
>>> next(lines)
(2, 'third line\n')

>>> f = open("test.txt")
>>> lines = enumerate(f)
>>> next(l for i, l in lines if i == 3)
'fourth line\n'

还有seek方法,它可以用来跳转到文件中的特定字符,这对于将文件“重置”到第一个位置(或者重新打开它)很有用,但是对于查找特定行没有多大帮助,除非您知道每行的确切长度(见下文)。
如果你想“以任意顺序读取任意行”,最简单的方法是使用readlines将所有行读入一个列表,然后访问该列表中的项(假设你的文件不是太大)。

>>> f = open("test.txt")
>>> lines = f.readlines()
>>> lines[3]
'fourth line\n'
>>> lines[1]
'second line\n'

我的目标是读取几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())
des4xlb0

des4xlb02#

当使用readline()时,文件对象(即来自open(file))表现为迭代器。本质上没有计数器。如果您运行file.__next__()代替file.readline(),则可以观察到这一点。
如果您不介意一次阅读整个文件,简单的解决方案是创建一个包含所有行的列表,然后引用您感兴趣的行,如

lines=file.readlines() # this is a list

相关问题