在计算机中,文件可以分为两种类型:文本文件和二进制文件。文本文件包含人类可读的字符,而二进制文件包含计算机指令或数据,无法直接阅读。常见的二进制文件包括图片、音频、视频、可执行文件等。
Python 提供了处理二进制文件的工具,允许你读写任意类型的数据。
1 以二进制模式打开文件
在 Python 中,操作二进制文件时,需要使用 'b'
作为文件模式的一部分。常见的二进制文件模式有:
'rb'
:以二进制读取文件。'wb'
:以二进制写入文件。'ab'
:以二进制追加内容到文件。
1.1 读取二进制文件 ('rb'
模式)
使用 'rb'
模式读取二进制文件时,文件内容将以字节形式读取。读取到的数据是一个 bytes
对象,而不是字符串。
# 以二进制模式读取文件
with open('image.png', 'rb') as file:
binary_data = file.read()
print(binary_data[:100]) # 打印前100个字节的数据
解释:
open('image.png', 'rb')
:以二进制模式打开一个图片文件。file.read()
:读取文件的全部内容,返回一个bytes
对象。binary_data[:100]
:只显示前100个字节的数据。
注意: 在读取二进制文件时,读取到的数据并不会被转换为可读的文本,而是直接以字节形式呈现。
1.2 写入二进制文件 ('wb'
模式)
使用 'wb'
模式写入二进制文件时,必须将写入的数据转换为字节类型。可以通过使用 bytes()
或其他数据类型来转换。
# 以二进制模式写入文件
with open('output.bin', 'wb') as file:
binary_data = bytes([120, 3, 255, 0, 100]) # 一个字节列表
file.write(binary_data)
解释:
bytes([120, 3, 255, 0, 100])
:创建一个包含字节数据的bytes
对象。file.write(binary_data)
:将字节数据写入文件。
写入二进制文件时,如果文件不存在,Python 会创建一个新文件。如果文件已经存在,它的内容将被覆盖。
1.3 追加二进制内容 ('ab'
模式)
使用 'ab'
模式可以向现有的二进制文件追加数据,而不会覆盖原有内容。
# 以二进制追加模式写入文件
with open('output.bin', 'ab') as file:
additional_data = bytes([200, 150, 50])
file.write(additional_data)
解释:
open('output.bin', 'ab')
:以二进制追加模式打开文件。file.write(additional_data)
:将额外的字节数据追加到文件末尾。
2 处理图片文件示例
图片文件是二进制文件的常见类型之一。以下是如何读取和写入图片文件的示例。
2.1 读取图片文件
以下代码展示了如何使用 Python 读取一个 PNG 图片文件的二进制数据。
# 读取 PNG 图片文件的二进制数据
with open('image.png', 'rb') as image_file:
image_data = image_file.read()
# 输出图片的前200个字节(可调整)
print(image_data[:200])
说明:
- 图片文件的数据是以字节的形式存储的,无法直接通过
print()
输出为可读的图片内容。 - 可以将读取到的二进制数据用于进一步处理,如显示图片、修改图片内容等。
2.2 写入图片文件
假设你有一段处理后的图片数据,想将其保存为新的图片文件。你可以使用二进制写入模式来完成此操作。
# 将数据写入一个新图片文件
with open('new_image.png', 'wb') as new_image_file:
new_image_file.write(image_data) # 假设 image_data 包含有效的二进制图片数据
此操作将把 image_data
中的字节数据写入到新创建的 new_image.png
文件中。
3 二进制文件与文本文件的区别
在处理二进制文件时,有几点需要注意:
- 数据格式不同:二进制文件包含的是原始字节,而不是字符。文本文件中的数据是字符的编码版本,通常以 Unicode 格式存储。
- 读取方式不同:文本文件的读取方式会自动将字节转换为字符串,而二进制文件的读取直接返回字节数据。
- 数据处理方式不同:操作二进制文件时,必须小心处理字节数据的格式和顺序。对于文本文件,Python 会自动处理字符编码和解码。
3.1 序列化与反序列化:使用 pickle
pickle
是 Python 中一个用于对象序列化和反序列化的模块。序列化是将 Python 对象转换为字节流的过程,反序列化是将字节流还原为原始对象的过程。这在处理二进制文件时非常有用,尤其是当你想要保存和加载复杂的 Python 数据结构时。
3.1.1 使用 pickle
序列化对象
以下代码展示了如何使用 pickle
将 Python 对象序列化并保存到二进制文件中:
import pickle
# 一个 Python 字典对象
data = {
'name': 'Alice',
'age': 30,
'city': 'New York'
}
# 将对象序列化并写入二进制文件
with open('data.pkl', 'wb') as file:
pickle.dump(data, file)
解释:
pickle.dump(data, file)
:将字典对象data
序列化并保存到文件data.pkl
中。'wb'
模式确保文件以二进制模式打开以保存字节流。
3.1.2 使用 pickle
反序列化对象
要从二进制文件中读取并还原序列化的对象,可以使用 pickle.load()
函数:
import pickle
# 从二进制文件中加载序列化对象
with open('data.pkl', 'rb') as file:
loaded_data = pickle.load(file)
print(loaded_data)
解释:
pickle.load(file)
:从文件data.pkl
中读取并反序列化对象,恢复为原始的 Python 数据结构。
3.2 二进制文件操作的常见应用
3.2.1 操作音频和视频文件
音频和视频文件也是典型的二进制文件。你可以使用类似的方式读取和写入这些文件,不过在处理这类文件时,通常会使用专门的库来解析和操作文件数据。
例如,可以使用 wave
模块处理 .wav
格式的音频文件:
import wave
# 读取一个 WAV 文件
with wave.open('audio.wav', 'rb') as audio_file:
# 获取音频的参数
params = audio_file.getparams()
print(params)
# 读取音频数据
frames = audio_file.readframes(audio_file.getnframes())
print(frames[:100]) # 打印前100个字节的音频数据
3.2.2 操作二进制数据流
处理原始二进制数据流通常用于网络通信或硬件控制。这类应用需要对数据格式有深刻的理解,并通常会使用 struct
模块来处理复杂的二进制数据格式。
import struct
# 定义一个二进制数据格式:一个整数和一个浮点数
data_format = 'i f'
# 创建二进制数据
binary_data = struct.pack(data_format, 1024, 3.14)
# 解包二进制数据
unpacked_data = struct.unpack(data_format, binary_data)
print(unpacked_data)
解释:
struct.pack(data_format, ...)
:将整数和浮点数打包为二进制数据。struct.unpack(data_format, binary_data)
:将二进制数据解包为原始的 Python 对象。