Pythonはバイトデータをどう読みますか?


問題
写真や音声ファイルなどバイナリファイルを読みたいです。
ソリューション
モードがrbまたはwbのオプン関数を使用して、バイナリデータを読み込みまたは書き込みます。たとえば:

# Read the entire file as a single byte string
with open('somefile.bin', 'rb') as f:
  data = f.read()

# Write binary data to a file
with open('somefile.bin', 'wb') as f:
  f.write(b'Hello World')
バイナリデータの読み取りには、テキスト文字列ではなく、返したデータはすべてバイト文字列フォーマットであることを指定する必要があります。同様に、書き込みの際には、パラメータがバイト形式で外部にデータを露出するオブジェクト(バイト文字列、バイト配列オブジェクトなど)であることを保証しなければならない。
討論する
バイナリデータを読み出す場合、バイト文字列とテキスト文字列の意味の違いは潜在的な落とし穴を引き起こすかもしれない。特に、インデックスおよび反復動作は、バイト文字列ではなくバイトの値を返します。たとえば:

>>> # Text string
>>> t = 'Hello World'
>>> t[0]
'H'
>>> for c in t:
...   print(c)
...
H
e
l
l
o
...
>>> # Byte string
>>> b = b'Hello World'
>>> b[0]
72
>>> for c in b:
...   print(c)
...
72
101
108
108
111
...
>>>
バイナリモードのファイルからテキストデータを読み込みまたは書き込みたい場合は、復号と符号化の操作を確実に行う必要があります。たとえば:

with open('somefile.bin', 'rb') as f:
  data = f.read(16)
  text = data.decode('utf-8')

with open('somefile.bin', 'wb') as f:
  text = 'Hello World'
  f.write(text.encode('utf-8'))
バイナリI/Oのもう一つのよく知られていない特性は、配列とC構造体タイプが直接書き込めます。中間的に自分の対象に変換する必要はありません。たとえば:

import array
nums = array.array('i', [1, 2, 3, 4])
with open('data.bin','wb') as f:
  f.write(nums)
これは、「バッファインターフェース」と呼ばれるオブジェクトを実現するための任意の用途に適しています。このオブジェクトは、その下のメモリバッファを直接暴露して処理できるようにします。バイナリデータの書き込みはこのような操作の一つです。
多くのオブジェクトはまた、ファイルオブジェクトのreadinto()方法を使用して、直接にバイナリデータを読み取り、その下のメモリに行くことができます。たとえば:

>>> import array
>>> a = array.array('i', [0, 0, 0, 0, 0, 0, 0, 0])
>>> with open('data.bin', 'rb') as f:
...   f.readinto(a)
...
16
>>> a
array('i', [1, 2, 3, 4, 0, 0, 0, 0])
>>>
しかし、この技術を使う時は、プラットフォームの相関があり、字長とバイト順(上位優先と下位優先)に依存する可能性があるので、特に注意が必要です。
以上はPythonがどうやってバイトデータを読むかの詳細です。Pythonはバイトデータを書く資料を読みます。他の関連記事に注目してください。