連載
» 2021年05月18日 05時00分 公開

[解決!Python]バイナリファイルを読み書きするには:文字列と整数編解決!Python

バイナリファイルを読み書きする基本と、文字列および整数をバイナリファイルに書き込む方法を紹介する。

[かわさきしんじ,Deep Insider編集部]

この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。

「解決!Python」のインデックス

連載目次

# 文字列のバイナリファイルへの書き込み
with open('test.bin', 'wb') as f:
    s = 'ディープインサイダー'
    b = s.encode()  # 文字列もバイト列にエンコードする必要がある
    f.write(b)  # バイナリファイルにはバイト列しか渡せない

# 文字列のバイナリファイルからの読み込み
with open('test.bin', 'rb') as f:
    b = f.read()
    s = b.decode()

print(s)  # ディープインサイダー

# 整数のバイナリファイルへの書き込みと読み込み
from sys import byteorder

print(byteorder)  # littleもしくはbig
length = 4  # 4バイト長整数に変換する

with open('test.bin', 'wb') as f:
    n = 123456
    b = n.to_bytes(length, byteorder)  # nを4バイト長の符号なし整数に変換
    f.write(b)

# 整数のバイナリファイルからの読み込み
with open('test.bin', 'rb') as f:
    b = f.read(length)  # lengthだけバイナリファイルから読み込み
    n = int.from_bytes(b, byteorder)  # バイト列を整数に変換する

print(f'read data: {n}'# read data: 123456

# 整数リストのバイナリファイルへの書き込みと読み込み
nlist = [1, 2, 3, 4, 5, 6]

with open('test.bin', 'wb') as f:
    # 整数リストをバイト列リストに変換してファイルに書き込み
    blist = [n.to_bytes(length, byteorder) for n in nlist]
    f.writelines(blist)
    # 整数リストをバイト列に変換してファイルに書き込み
    #b = b''.join([n.to_bytes(length, byteorder) for n in nlist])
    #f.write(b)

# バイナリファイルからの整数の連続読み込み
with open('test.bin', 'rb') as f:
    result = []
    b = f.read(length)  # lengthだけバイナリファイルから読み込み
    while b:  # データがあるだけ以下を繰り返す
        n = int.from_bytes(b, byteorder)  # 読み込んだデータを整数に変換
        result.append(n)  # リストに追加
        b = f.read(length)  # lengthだけバイナリファイルから読み込み

print(result)  # [1, 2, 3, 4, 5, 6]

# バイト列を読み込んだ後にmemoryviewオブジェクトを得て、型変換を行う
with open('test.bin', 'rb') as f:
    b = f.read()

mv = memoryview(b)
result = mv.cast('i').tolist()
print(result)  # [1, 2, 3, 4, 5, 6]


バイナリファイルを読み書きする基本

 バイナリファイルを読み書きする際には、open関数のmode引数に'b'を付加する(読み込みなら'rb'、書き込みなら'wb')。

# バイナリファイルを読み込みモードでオープンする
with open('filename', 'rb') as f:
    pass  # ファイルを利用する

# バイナリファイルを書き込みモードでオープンする
with open('filename', 'wb') as f:
    pass  # ファイルを利用する


 オープンしたファイルに対しては、テキストファイルと同様に、readメソッドやwriteメソッドなどを呼び出せる。

 バイナリファイルを読み込み用にオープンしたときには、以下のように反復可能オブジェクトとしてfor文にファイルを渡すことも可能だ。

with open('filename', 'rb') as f:
    for data in f:  # 行末(\n)またはEOFまでを読み込んで以下を繰り返す
        pass  # 何かの処理を行う


 上のような形でバイナリファイルから読み込むときには改行文字は常に「\n」となる点は覚えておこう。

 特定のバイト数だけを読み込むのであれば、readメソッドに読み込みたいバイト数を指定する。

with open('filename', 'rb') as f:
    size = 32
    data = f.read(size)
    while data:
        # 何かの処理を行う
        data = f.read(size)


 バイナリファイルの読み込みを行うと、得られるのは「バイト列」(bytes型のオブジェクト)になっている点には注意しよう。それらは何らかの形で特定の型のオブジェクトに変換する必要がある。

 バイナリファイルを書き込み用にオープンしたときには、元のデータを「バイト列」に変換したものをwriteメソッドなどで書き込んでいく。

with open('filename', 'wb') as f:
    s = 'hello'
    b = s.encode()  # 文字列をバイト列に変換
    f.write(b)  # 変換後のバイト列をバイナリファイルに書き込み


 以下では、バイナリファイルへの書き込みの例として、文字列と整数を取り上げる。これら以外のオブジェクトは次回に説明をするstructモジュールを使用することでバイナリファイルへの書き込みが比較的簡単に行えるようになる。

バイナリファイルに対して文字列を読み書きする

 文字列にはバイト列への変換を行うencodeメソッドがあり、バイト列には文字列への変換を行うdecodeメソッドがある。

 バイナリファイルに文字列を書き込む例を以下に示す。

with open('test.bin', 'wb') as f:
    s = 'ディープインサイダー'
    b = s.encode()  # 文字列もバイト列にエンコードする必要がある
    f.write(b)


 この例では、バイナリファイルを書き込みモードでオープンした後、文字列sのencodeメソッドを呼び出してバイト列にエンコードして、それをwriteメソッドで書き出している。なお、encodeメソッドのencoding引数にエンコーディングを指定することも可能だ。

 次にバイナリファイルの読み込みの例を示す。

with open('test.bin', 'rb') as f:
    b = f.read()
    s = b.decode()

print(s)  # ディープインサイダー


 このコードでは、バイナリファイルを読み込み用にオープンして、readメソッドで全ての内容を読み出して、取得したバイト列をdecodeメソッドで文字列にデコードしている。文字列のencodeメソッドと同様に、バイト列のdecodeメソッドでもエンコーディングを指定できる。

バイナリファイルに対して整数を読み書きする

 文字列とバイト列の変換には文字列のencodeメソッド/バイト列のdecodeメソッドを使用したが、整数とバイト列の変換には整数型(int型)のto_bytesインスタンスメソッドとfrom_bytesクラスメソッドを使用する。

 to_bytesメソッドの構文は以下の通り。

int.to_bytes(length, byteorder, signed=False)


 length引数とbyteorder引数は指定が必須で、signed引数は省略可能なキーワード専用引数である。length引数は整数を何バイトのバイト列に変換するかを指定する。byteorder引数はバイトオーダーの指定で、signed引数は2の補数を使用するかどうかの指定となる(負数をバイト列に変換する場合には「signed=True」のようにキーワードを明示して指定)。

Copyright© Digital Advantage Corp. All Rights Reserved.

編集部からのお知らせ

6月16日にフォーマット統一のため利用規約を変更します

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。