【Python】バイナリファイルを読み書きモードで新規作成して開く(モードw+b)【入門第68回】

200, 2019-09-27

目次

バイナリファイルを読み書きモードで新規作成

こんにちは、narupoです。

バイナリファイルを読み書きモードで新規作成して開くにはopen関数のmode引数に文字列w+bを指定します。
このモードはファイルが存在しない場合はファイルを新規作成し、ファイルがすでに存在する場合はファイルの中身を空にしてファイルを開きます。
このモードで得られるファイルオブジェクトは_io.BufferedRandomです。
ファイルオブジェクトのread, writeメソッドなどを使うとファイルを読み書きすることが出来ます。

今回は具体的には↓を見ていきます。

  • バイナリファイルを読み書きモードで新規作成して開く

  • io.BufferedRandomの詳細

  • バイナリファイルにデータを書き込む

  • バイナリファイルからデータを読み込む

  • データを書き込んでから読み込む

ほかのファイル入出力についての入門記事は↓をご覧ください。

バイナリファイルを読み書きモードで新規作成して開く

バイナリファイルを読み書きモードで新規作成して開くにはopen関数を↓のようにして使います。

with open('alphas.dat', mode='w+b') as fp:
    pass

open関数の第1引数にファイルのパスを指定します。
mode引数にモードを表す文字列w+bを指定します。

このモードのopen関数は、ファイルが存在しない場合はファイルを新規作成してファイルを開きます。
ファイルがすでに存在する場合はファイルの中身を空にしてファイルを開きます
大切なデータが入っているファイルを空にしてしまわないように注意しましょう。

open関数の詳しい使い方については↓の記事をご覧ください。

io.BufferedRandomの詳細

r+bモードのopen関数から得られるファイルオブジェクトは_io.BufferedRandomです。

with open('alphas.dat', mode='r+b') as fp:
    print(type(fp))

↑のコードの実行結果は↓のようになります。

<class '_io.BufferedRandom'>

公式のドキュメントは↓です。

io.BufferedRandomio.BufferedReaderおよびio.BufferedWriterを継承したクラスです。

io.BufferedReaderおよびio.BufferedWriterはそれぞれio.BufferedIOBaseを、io.BufferedIOBaseio.IOBaseを継承しています。

これらのクラスの公式ドキュメントを参照すれば利用できるメソッドを一望することが出来ます。

バイナリファイルにデータを書き込む

w+bモードで開いたバイナリファイルにデータを書き込むにはwriteメソッドを使います。

with open('alphas.dat', mode='w+b') as fp:
    fp.write(b'abc')

↑のコードを実行するとalphas.datが新規作成されます。
alphas.datの中身は↓のようになります。

abc

writeメソッドで書き込めるデータはバイト列かバイト列に相当するオブジェクトに限られます。

バイナリファイルへの書き込みについて詳しく知りたい方は↓の記事をご覧ください。

バイナリファイルからデータを読み込む

w+bモードで開いたバイナリファイルからデータを読み込むにはreadメソッドなどを使います。

with open('alphas.dat', mode='w+b') as fp:
    data = fp.read()
    print(data)

↑のコードの実行結果は↓のようになります。

b''

w+bモードでファイルを開くと、開いた直後のファイルの中身は空になっています。
そのためreadで読み込んでも↑のように空のバイト列が返ってきます。

バイナリファイルからの読み込みについて詳しく知りたい方は↓の記事をご覧ください。

データを書き込んでから読み込む

いったんファイルにデータを書き込んで、そのデータを読み込みたい場合は↓のようにします。

import os

with open('alphas.dat', mode='w+b') as fp:
    # データを書き込む
    fp.write(b'abc')

    # ファイルのオフセット位置をファイル先頭に移動する
    fp.seek(0, os.SEEK_SET)

    # データをファイル先頭から読み込む
    data = fp.read()
    print(data)

↑のコードの実行結果は↓のようになります。

b'abc'

ファイルオブジェクトは内部にファイルのオフセット位置を持っています。
ファイルオブジェクトはこのオフセット位置を基準にしてファイルを読み書きします。
このオフセット位置はwriteメソッドやreadメソッドを使うと自動でファイル末尾に向かって進みます。
そのため、↑の例ではwriteメソッドを読んだ後にファイルのオフセット位置をファイルの先頭に戻しています。
そうすることでreadではファイルの先頭からデータを読み込むことが出来るようになります。

seekメソッドは第1引数に基点からの相対位置、第2引数に基点位置を指定します。
os.SEEK_SETはファイル先頭を表す定数です。
そのためseek(0, os.SEEK_SET)は「ファイル先頭から0の位置にオフセット位置を移動する」という意味になります。
つまり、ファイル先頭にオフセット位置を移動してるわけです。

ランダムアクセスについて詳しく知りたい方は↓の記事をご覧ください。

  • [TODO: リンク(ランダムアクセス)]

おわりに

w+bモードはファイルを破壊的に開くため、なかなかデンジャーなモードです。
うまいことr+ba+b, x+bと使い分けるようにしましょう。

また見てね

関連動画





スポンサーリンク

スポンサーリンク

スポンサーリンク

スポンサーリンク