python cookbook 学习笔记 第五章 文件与IO (4) 读写字节数据

  • 读写字节数据
  • 问题:
    • 想读取二进制文件,比如图片,声音文件等等。
  • 解决方案:
    • 使用模式为rb 或者 wb 的 open()函数来读取或者写入二进制数据:
with open("1.jpg","rb") as f,\
        open("test1.jpg","wb") as w:
    data = f.read()
    w.write(data)
  • 在读取二进制数据时,需要指明的是所有返回的数据都是字节字符串格式的,而不是文本字符串。类似的,在写入的 时候,必须保证参数是以字节形式对外暴露数据的对象(比如字节字符串,字节数字对象等)。

  • 讨论: 在读取二进制数据的时候,字节字符串和文本字符串的语义差异可能回导致一个潜在的陷阱。特别注意的是 索引和迭代动作返回的是字节的值二不是字节字符串:

t = "hello world"
for c in t:
    print(c)

b = b"hello world"
for c in b:
    print(c, end= " ")
# 104 101 108 108 111 32 119 111 114 108 100
  • 如果像从二进制模式的文件中读取或者写入文本数据,必须确保要进行解码和编码操作:
with open("somefile.bin", "rb") as f:
    data = f.read(16)
    text = data.decode("utf-8")

with open("somefile.bin", "wb") as f:
    text1 = "hello world"
    f.write(text1.encode("utf-8"))
  • 二进制 I/O 还有一个特性就是数组合 C 结构体类型能直接被写入,而不需要中间转换。比如:
import array
nums = array.array("i", [1, 2, 3, 4])
with open("test3.bin", "wb") as f:
    f.write(nums)
  • 这个适用于任何实现了”缓冲接口“的对象,这种对象会直接暴露其底层的内存缓冲区给能处理它的操作。二进制数据 的写入就是这类操作之一。
  • 很多对象还允许通过使用文件对象的 readinto()方法直接读取二进制数据到其底层的内存中去:
a = array.array("i",[0, 0, 0, 0, 0, 0, 0, 0])
with open("test3.bin", "rb") as f:
    f.readinto(a)

print(a)
# array('i', [1, 2, 3, 4, 0, 0, 0, 0])
  • 这种技术通常具有平台相关性,并且可能会依赖字长和字节顺序(高位优先和低位优先)

猜你喜欢

转载自blog.csdn.net/qq_43539055/article/details/84889078