Skip to content

文件读取

使用 open() 函数打开文件会创建并返回一个文件对象,可以在该对象上执行以下活动:

顺序读取

可以在文件对象上使用以下三种方法按顺序读取文件的内容:

read()

read(size = -1) 方法用于一次从文件中读取 size 个字节(二进制模式)或字符(文本模式)的数据。

如果未指定 size 或为负数,它会读取并返回文件的全部内容。

示例

让我们考虑一个名为 info.txt 的文件,包含以下文本(假设 UTF-8 编码):

你好 世界
谢谢

代码

python
>>> with open('info.txt', 'r', encoding='utf-8') as f:
...     print(f.read(3)) # 读取 3 个字符
...
你好
>>> with open('info.txt', 'r', encoding='utf-8') as f:
...     print(f.read(4)) # 读取 4 个字符
...
你好 世
>>> # 重新打开文件
>>> with open('info.txt', 'r', encoding='utf-8') as f:
...     print(f.read()) # 读取所有内容
...
你好 世界
谢谢
>>>

readline()

readline(size = -1) 方法在不带任何参数时,用于一次从给定文件中读取并返回一行(直到并包括换行符 \n)。

如果指定了 size,它最多返回 size 个字节/字符的数据,或者直到遇到换行符为止的数据。

示例

让我们考虑一个名为 info.txt 的文件,包含以下文本:

你好 世界
谢谢

代码

python
>>> with open('info.txt', 'r', encoding='utf-8') as f:
...     print(repr(f.readline(3))) # 读取最多 3 个字符
...
'你好 '
>>> # 重新打开
>>> with open('info.txt', 'r', encoding='utf-8') as f:
...     print(repr(f.readline())) # 读取第一行
...
'你好 世界\n'
>>>     print(repr(f.readline())) # 读取第二行
...
'谢谢'
>>>     print(repr(f.readline())) # 文件末尾,返回空字符串
...
''
>>>

由于 readline() 一次返回一行,因此可以在 while 语句中使用它逐行迭代数据。当到达文件末尾时,它返回一个空字符串。

代码

python
with open('info.txt', 'r', encoding='utf-8') as f:
    line = f.readline()
    while line:
        #移除行尾的换行符和其他空白
        line = line.strip()

        print(line)

        #读取下一行
        line = f.readline()

输出

你好 世界
谢谢

for 语句也可以用于逐行遍历文件,无需 readline() 方法。只需迭代文件对象即可一次返回一行数据。这是遍历文件的首选方式。

代码

python
with open('info.txt', 'r', encoding='utf-8') as f:
    for line in f:
        #移除行尾的换行符和其他空白
        line = line.strip()
        print(line)

输出

你好 世界
谢谢

readlines()

readlines() 方法返回一个字符串列表,表示文本文件内容的行(包括换行符)。对于大文件,这可能会消耗大量内存,通常不推荐。

示例

让我们考虑一个名为 info.txt 的文件,包含以下文本:

你好 世界
谢谢

代码

python
>>> with open('info.txt', 'r', encoding='utf-8') as f:
...     print(f.readlines())
...
['你好 世界\n', '谢谢']

随机读取 (Ad-hoc Reading)

可以在文件对象上使用以下两种方法随机访问文件的内容:

tell()

tell() 返回文件对象在文件中的当前字节位置(整数)。

让我们考虑相同的文件 info.txt(假设 UTF-8 编码,'你好 ' 占 7 字节)。

python
>>> with open('info.txt', 'rb') as f: # 注意使用二进制模式 'rb'
...     f.read(7) # 读取 7 字节
...     print(f.tell())
...
7

注意: 在文本模式下,tell() 返回的值可能不直接对应字节数,因此随机访问通常在二进制模式下进行。

seek()

seek(offset, reference=0) 可用于在文件对象中定位到相对于 reference 偏移 offset 个字节的位置。

reference 的默认值是 0,代表文件开头。对于此默认 referenceoffset 必须是非负整数。

reference 的其他允许值是:

  • 1,表示偏移量将从文件对象的当前位置计算(offset 可以是正数或负数)
  • 2,表示偏移量从文件末尾计算(offset 通常是负数)

注意:在文本文件(模式字符串中没有 b 的文件)中,只允许相对于文件开头 (reference = 0) 的 seek 操作,除非 offset 是 0,或者 offset 是之前 tell() 返回的值。reference = 1 或 2 仅在以二进制模式打开文件时有效。

让我们考虑相同的文件 info.txt,并在二进制模式下操作。

python
>>> with open('info.txt', 'rb') as f:
...     print(f.seek(6)) # 定位到第 6 个字节
...     # 文件指针位置: 你好 |世界\n谢谢 ('|' 表示指针)
...     print(f.read().decode('utf-8')) # 读取剩余内容并解码
...     print(f.tell()) # 文件总字节数 (假设 14)
...
6
 世界
谢谢
14
>>> # 重新打开并从末尾定位
>>> with open('info.txt', 'rb') as f:
...     print(f.seek(-6, 2)) # 从末尾向前偏移 6 字节
...     # 文件指针位置: 你好 世界\n|谢谢 ('|' 表示指针)
...     print(f.read().decode('utf-8'))
...
10 # '谢谢' 占 6 字节,所以是从第 10 字节开始
谢谢