python - Python 文件 read() 和 readline() 计数器?
问题描述
看起来 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()
''
>>>
解决方案
Python 中的文件对象是一个迭代器,迭代文件中的不同行。您可以使用readlines()
一次将所有(剩余)行读取到列表中,或者read()
读取文件中的单个或所有(剩余)字符(默认为全部,使用参数来读取要读取的字符数),但是默认行为(如果您直接迭代文件)与 with 相同readline
,即从文件中产生下一行。
您可以将其与enumerate
获得另一个迭代器产生行号以及每行(0
除非您指定enumerate
'sstart
参数,否则第一行具有编号),或获取特定行:
>>> 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())
推荐阅读
- node.js - Firebase function always timeout on large files?
- r - svyglm function how to change the catergoircal variable in the summary
- javascript - 使跨度的输出成为输入的值
- flutter - Iterator current is null, but why?
- firebase - Merging streams together to create paginated ListView
- r - 从R中的Word文档中提取项目符号
- batch-file - 如何精确选择数字的一部分作为简单字符并在 CMD 中排除所有其余部分?
- jquery - 仅当动态创建的类匹配时拖放
- visualization - Pyvista 已经是一个完整的库了吗?[2021年1月]
- python - 使用 BeautifulSoup 4 引用 Html 标签内的两个类