IO 流
I/O 流(Input/Output Stream) 是程序中用于处理输入和输出的机制。在 Python 中,I/O 流主要用于读写文件、处理网络数据、与用户交互等操作。
1. I/O 流的基本概念
I/O 流是数据在程序和外部设备(如文件、网络、终端等)之间流动的通道。Python 的 I/O 流分为两种:
- 文本流(Text Stream):处理文本数据,默认使用 Unicode 编码。
- 二进制流(Binary Stream):处理二进制数据,如图片、音频、视频等。
2. 文件 I/O
文件 I/O 是最常见的 I/O 操作,Python 提供了内置的 open() 函数来操作文件。
2.1 打开文件
使用 open() 函数打开文件,语法如下:
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
file:文件路径(字符串或字节)。mode:打开文件的模式(见下表)。encoding:文本文件的编码方式(如'utf-8')。- 返回值:返回一个文件对象。
| 模式 | 描述 |
|---|---|
r |
字符模式打开文件。只读。文件指针在文件开头。文件不存在会报错 |
rb |
同上,字节模式 |
r+ |
字符模式打开文件。读写。文件指针在文件开头。文件不存在会报错 |
rb+ |
同上,字节模式 |
w |
字符模式打开文件。只写。文件指针在文件开头。 如果文件不存在就新建,如果存在就清空内容准备写入 按这种模式一打开文件,内容就会被清空 |
wb |
同上,字节模式 |
w+ |
字符模式打开文件。读写。文件指针在文件开头。 如果文件不存在就新建,如果存在就清空内容准备写入 按这种模式一打开文件,内容就会被清空,所以只能读取到本次写入的内容 |
wb+ |
同上,字节模式 |
a |
字符模式打开文件。只写(末尾写入)。文件指针在文件末尾。 文件不存在会新建,存在就打开,不会清空内容。文件指针在文件末尾 |
ab |
同上,按字节模式 |
a+ |
字符模式打开文件。读写(末尾写入)。文件指针在文件末尾。 文件不存在会新建,存在就打开,不会清空内容。文件指针在文件末尾 |
ab+ |
同上,字节模式 |
示例
# 打开一个文本文件(只读模式)
file = open('example.txt', 'r', encoding='utf-8')
# 打开一个文本文件(写入模式,只要文件一打开,内容就被清空了)
file = open('test.txt', 'w', encoding='utf-8')
2.2 读取文件
文件对象提供了多种读取数据的方法:
| 方法 | 描述 |
|---|---|
read(size) |
读取指定大小的数据(字节或字符),默认读取全部内容。 |
readline() |
读取一行数据。 |
readlines() |
读取所有行,返回一个列表。 |
for line in file: |
逐行读取文件(推荐方式)。 |
示例
# 读取整个文件,不带参数就读全部,带参数表示读取指定数量的字符或字节(看什么模式打开的文件)
content = file.read()
print(content)
# 逐行读取文件
for line in file:
print(line)
# 读取一行
line = file.readline()
print(line)
# 读取所有行
lines = file.readlines()
print(lines)
2.3 写入文件
文件对象提供了多种写入数据的方法:
| 方法 | 描述 |
|---|---|
write(string) |
写入字符串数据。 |
writelines(lines) |
写入多行数据(列表或迭代器)。 |
示例
# 写入字符串
file.write("Hello, World!\n")
# 写入多行数据
lines = ["Line 1\n", "Line 2\n", "Line 3\n"]
file.writelines(lines)
2.4 关闭文件
使用 close() 方法关闭文件,释放资源。
file.close()
使用 with 语句(推荐)
with 语句可以自动管理文件的打开和关闭,避免资源泄漏。
with open('example.txt', 'r', encoding='utf-8') as file:
content = file.read()
print(content)
# 文件会在 with 块结束后自动关闭
3. 文件指针
文件读到哪指针就移动到哪,写入一样的,写到哪指针就在哪。如果是字符模式,就是第几个字符的位置
文件指针的基本概念
- 文件指针:文件指针是一个标记,表示当前文件读写的位置。
- 默认行为:
- 打开文件时,文件指针的位置取决于打开模式:
'r'和'r+':文件指针位于文件开头。'w'和'w+':文件指针位于文件开头(但文件内容会被清空)。'a'和'a+':文件指针位于文件末尾。
- 打开文件时,文件指针的位置取决于打开模式:
- 移动文件指针:通过
seek()函数可以移动文件指针。 - 获取文件指针位置:通过
tell()函数可以获取当前文件指针的位置。
seek() 函数
seek() 函数用于移动文件指针到指定位置
file.seek(offset, whence)
offset:移动的字节数(偏移量)。- 正数:向文件末尾方向移动。
- 负数:向文件开头方向移动。
whence:参考位置,可选参数,默认为0。0:从文件开头计算偏移量。1:从当前文件指针位置计算偏移量。2:从文件末尾计算偏移量。
tell() 函数
tell() 函数用于获取当前文件指针的位置。
file.tell()
文件指针的注意事项
- 文本模式和二进制模式的区别:
- 在 文本模式 下,
seek()和tell()的行为可能会受到编码的影响(如utf-8编码中,某些字符可能占用多个字节)。 - 在 二进制模式 下,
seek()和tell()的行为是精确的,以字节为单位。
- 在 文本模式 下,
- 文件指针的移动范围:
- 文件指针不能移动到文件开头之前或文件末尾之后。
- 如果
seek()的偏移量超出文件范围,会抛出ValueError。
- 写入操作的影响:
- 写入操作会从当前文件指针位置开始,并移动文件指针到写入内容的末尾
示例
# 假设文件 example.txt 内容为:Hello, World!
with open('text.text', 'r+', encoding='utf-8') as file:
# 读取前 5 个字符
print(file.read(5)) # 输出: Hello
# 获取当前文件指针位置
print("当前指针位置:", file.tell()) # 输出: 当前指针位置: 5
# 将文件指针移动到文件开头
file.seek(0)
print("移动后指针位置:", file.tell()) # 输出: 移动后指针位置: 0
# 读取文件内容
print(file.read()) # 输出: Hello, World!
# 将文件指针移动到文件末尾
file.seek(0, 2)
print("移动后指针位置:", file.tell()) # 输出: 移动后指针位置: 13
# 指针移动到第5个字符(也就是 o 后面,Hello| )
file.seek(5, 0)
print(f"11当前指针位置: {file.tell()}") # 输出:11当前指针位置: 5
print(file.read()) # 输出 , World!
4. 中间插入
示例1
假设文件 example.txt 的内容如下:
Line 1
Line 2
Line 3
Line 4
我们希望在 Line 2 和 Line 3 之间插入一行 New Line
# 文件路径
file_path = 'example.txt'
# 要插入的文本
new_text = "New Line\n"
# 打开文件并读取所有内容
with open(file_path, 'r', encoding='utf-8') as file:
lines = file.readlines() # 读取所有行,返回一个列表
# 找到插入位置(在 Line 2 和 Line 3 之间)
insert_index = 2 # 在第 2 行之后插入(索引从 0 开始)
# 在内存中插入新内容
lines.insert(insert_index, new_text)
# 将修改后的内容写回文件
with open(file_path, 'w', encoding='utf-8') as file:
file.writelines(lines) # 将列表写入文件
# 输出修改后的文件内容
with open(file_path, 'r', encoding='utf-8') as file:
print("修改后的文件内容:")
print(file.read())
修改后的文件内容:
Line 1
Line 2
New Line
Line 3
Line 4
示例2
假设文件 example.txt 的内容如下:
Line 1
Line 2
Line 3
Line 4
我们希望在 Line 2 和 Line 3 之间插入一行 New Line
# 文件路径
file_path = 'example.txt'
# 要插入的文本
new_text = "New Line\n"
# 打开文件(使用 'r+' 模式支持读写)
with open(file_path, 'r+', encoding='utf-8') as file:
# 找到插入点(在 Line 2 和 Line 3 之间)
# 假设每行长度固定,或者通过逐行读取找到插入点
file.seek(0) # 将文件指针移动到开头
lines = file.readlines() # 读取所有行
insert_index = 2 # 在第 2 行之后插入(索引从 0 开始)
# 计算插入点的字节位置
file.seek(0) # 重新将文件指针移动到开头
insert_position = 0
for i, line in enumerate(lines):
if i == insert_index:
break
insert_position += len(line.encode('utf-8')) # 计算字节位置
# 读取插入点之后的内容
file.seek(insert_position) # 移动文件指针到插入点
remaining_content = file.read() # 读取插入点之后的内容
# 写入新内容和剩余内容
file.seek(insert_position) # 移动文件指针到插入点
file.write(new_text) # 写入新内容
file.write(remaining_content) # 写入剩余内容
# 输出修改后的文件内容
with open(file_path, 'r', encoding='utf-8') as file:
print("修改后的文件内容:")
print(file.read())
修改后的文件内容:
Line 1
Line 2
New Line
Line 3
Line 4

浙公网安备 33010602011771号