はじめに
PythonのI/O操作は選択肢が多く、コーディング時、
どのクラスのメソッドを使うべきか、迷う場合あります。
自己メモ兼ねて、I/Oの全体像をまとめてみました。
I/Oのベースはファイルオブジェクト
(ストリーム
、file-likeオブジェクト
と同義)
ファイルオブジェクトの定義をPython用語集から抜粋
- 下位リソースに対するファイル指向APIを提供
-
read()
メソッド -
write()
メソッド
-
- 下記リソースへのアクセス手段を提供
- ディスク上ファイル
- その他ストレージ
- 通信デバイス
- 標準入出力
- インメモリバッファ
- ソケット
- パイプ
ファイルオブジェクトの種類
- Text File
- テキストファイル
- Buffered Binary File
- バッファリング付きバイナリファイル
- Raw Binary File
- バッファリングなしバイナリファイル
ファイルオブジェクト操作のインターフェス
io
モジュールに定義されている
io
モジュールの定義をPythonドキュメントから抜粋
- ストリーム(=ファイルオブジェクト)を扱うコアツールで、様々な種類のI/Oを提供
- テキストストリームの
Text I/O
-
str
オブジェクトを受け取り(INPUT)、str
オブジェクトを生成(OUTPUT) - データのエンコード・デコードを行う
- 改行文字変換を行う(オプショナル。プラットフォーム依存)
- テキストストリーム作成サンプル
f = open("myfile.txt", "r", encoding="utf-8")
-
- バイナリストリームの
Binary I/O
(Buffered I/O)-
bytes-like
オブジェクトを受け取り(INPUT)、bytes
オブジェクトを生成(OUTPUT) - データのエンコード、デコードを行わない
- 改行文字変換を行わない
- 非テキストデータだけでなく、テキストデータを自前処理したい場合も使用
- バイナリストリームの作成サンプル
f = open("myfile.jpg", "rb")
-
- Rawストリームの
Raw I/O
(Unbuffered I/O)- バイナリストリームやテキストストリームの低レベル部品
- ユーザーコードで直接扱うべき場面は滅多にない
- Rawストリームの作成サンプル(バッファリングを無効にし、ファイルをバイナリーモードで開く)
f = open("myfile.jpg", "rb", buffering=0)
- バイナリストリームやテキストストリームの低レベル部品
- テキストストリームの
- ストリーム操作モード
- 読み込み専用
- 書き込み専用
- 読み書き
- ストリームアクセス方向
- ランダムアクセス
- 前方、後方の任意の場所にシーク
- シーケンシャルアクセス
- 一方向のみ(例えば、ソケットやパイプなど)
- ランダムアクセス
- ストリームのデータ型
- バイナリストリームは、
bytes
オブジェクトのみサポート - テキストストリームは、
str
オブジェクトのみサポート
- バイナリストリームは、
ストリームI/Oの検証
目的は、各種ストリームのINPUT、OUTPUTを確認。
テキストストリーム(Text I/O
)
- テキストファイル
test_file
を作成
中身は漢字2文字(文字コードはUTF-8)
検証
- test_fileを読み込み専用、テキストモードで開く、
> python
>>> f = open("test_file", "r", encoding="utf-8")
openされたテキストストリームのタイプを確認すると、
TextIOWrapper
クラスとなっています。
>>> type(f)
<class '_io.TextIOWrapper'>
ストリームを読み込むと、そのデータタイプは、
str
クラスとなっています。
>>> data = f.read()
>>> type(data)
<class 'str'>
読み込まれたデータを出力すると、
漢字2文字検証
が出力されます。
>>> print(data)
検証
バイナリストリーム(Binary I/O)
- test_fileを読み込み専用、バイナリモードで開く、
> python
>>> f = open("test_file", "rb")
openされたテキストストリームのタイプを確認すると、
BufferedReader
クラスとなっています。
>>> type(f)
<class '_io.BufferedReader'>
ストリームを読み込むと、そのデータタイプは、
bytes
クラスとなっています。
>>> data = f.read()
>>> type(data)
<class 'bytes'>
読み込まれたデータを出力すると、
16進で6バイト出力されます。
>>> print(data)
b'\xe6\xa4\x9c\xe8\xa8\xbc'
漢字2文字検証
のUTF-8コードを確認すると、
※ 参照: Unicode対応 文字コード表
検
: E6A49C
証
: E8A8BC
となり、上記バイト列と一致していることがわかりました。
Rawストリーム(Raw I/O)
- test_fileを読み込み専用、バッファリングを無効に、バイナリモードで開く、
> python
>>> f = open("test_file", "rb", buffering=0)
openされたテキストストリームのタイプを確認すると、
FileIO
クラスとなっています。
>>> type(f)
<class '_io.FileIO'>
ストリームを読み込むと、そのデータタイプは、
bytes
クラスとなっています。
>>> data = f.read()
>>> type(data)
<class 'bytes'>
読み込まれたデータを出力すると、
16進で6バイト出力されます。
>>> print(data)
b'\xe6\xa4\x9c\xe8\xa8\xbc'
漢字2文字検証
のUTF-8コードと一致します。
バイナリストリームと同じ結果となりました。
おわりに
Pythonのストリーム種類とI/Oを検証してみました。
バッファリングあり・なしの違いが気になりますが、
次回のお楽しみとさせてください。