io --- 入出力ストリーム¶
このモジュールには、追加の種類の stream (ファイルライク)オブジェクトとヘルパー関数が含まれています。標準の read/write/seek ストリームインターフェイスを実装するメモリ内のテキストおよびバイナリバッファ(StringIO、BytesIO)とともに、組み込みの open() を公開します。
概念上の階層¶
CPython との違い
ストリーム基底クラスの概念上の階層は、本節で説明するように MicroPython では簡略化されています。
すべての具象クラスの動作の基盤となる(抽象)基底ストリームクラスは、CPython ではいくつかの二分法(対をなす分類)に従っています。MicroPython では、より高い効率を実現しリソースを節約するために、これらはいくらか簡略化され、暗黙的なものとなっています。
CPython における重要な二分法の一つは、バッファなしストリームとバッファありストリームの区別です。MicroPython では、現在すべてのストリームがバッファなしです。これは、すべての現代的な OS、さらには多くの RTOS やファイルシステムドライバが、すでにそれら自身の側でバッファリングを行っているためです。さらに別のバッファリング層を追加することは逆効果であり(「バッファブロート」として知られる問題)、貴重なメモリを消費します。なお、バッファリングが有用なケースは依然として存在するため、後日オプションのバッファリングサポートを導入する可能性があります。
しかし CPython では、もう一つの重要な二分法が「バッファありか否か」と結び付いています。それは、ストリームが短い読み書き(short read/write)を起こしうるかどうかです。短い読み取りとは、ユーザーがたとえばストリームから 10 バイトを要求したのにそれ未満しか得られない場合であり、書き込みでも同様です。CPython では、バッファなしストリームは自動的に短い操作を起こしうる一方、バッファありストリームはそれらに対して保証があります。短い読み書きがないという特性は重要であり、より簡潔で効率的なプログラムの開発を可能にします。これは MicroPython にとって非常に望ましいものです。そのため、MicroPython はバッファありストリームをサポートしていませんが、それでも短い操作のないストリームを提供します。短い操作が発生するかどうかは個々のクラスのニーズに依存しますが、開発者は前述の理由から短い操作のない動作を優先することを強く推奨します。たとえば、MicroPython のソケットは短い読み書きを回避することが保証されています。実際のところ、現時点ではコアの中に短い操作を行うストリームクラスの例はなく、そのようなクラスは特定のハードウェアに固有のものとなるでしょう。
短い操作のない動作は、ノンブロッキングストリームの場合に扱いが難しくなります。ブロッキングとノンブロッキングの動作の区別は CPython のもう一つの二分法であり、MicroPython によって完全にサポートされています。ノンブロッキングストリームは、データの到着や書き込みを決して待たず、可能なものを読み書きするか、データがない(またはデータを書き込めない)ことを通知します。これは明らかに「短い操作なし」ポリシーと衝突します。実際、ノンブロッキングでバッファあり(つまり短い操作なし)のストリームというケースは CPython では入り組んでいます。一部の箇所ではそのような組み合わせが禁止され、一部では未定義あるいは単に文書化されておらず、一部のケースでは冗長な例外が送出されます。この問題は MicroPython ではずっと単純です。ノンブロッキングストリームは効率的な非同期操作にとって重要であるため、この性質が「短い操作なし」の性質よりも優先されます。したがって、ブロッキングストリームは可能な限り短い読み書きを回避しますが(短い読み取りが発生する唯一のケースは、ファイル終端に達した場合か、エラーの場合です(ただしエラーは短いデータを返すのではなく例外を送出します))、ノンブロッキングストリームは操作のブロックを避けるために短いデータを生成することがあります。
最後の二分法は、バイナリストリームとテキストストリームの区別です。MicroPython はもちろんこれらをサポートしていますが、CPython ではテキストストリームが本質的にバッファありであるのに対し、MicroPython ではそうではありません。(実際、これはバッファリングサポートを導入する可能性のあるケースの一つです。)
なお、効率のため、MicroPython は上記の階層に対応する抽象基底クラスを提供しておらず、純粋な Python でストリームクラスを実装したりサブクラス化したりすることはできません。
関数¶
クラス¶
- class io.IOBase¶
ストリーム(「ファイルライク」)オブジェクトの基底クラスです。具象サブクラスは以下の低レベル I/O メソッド(
readinto、write、ioctl)を実装します。ランタイムはそれらの上に高レベルのストリームプロトコル(read、readline、readlines、close、反復処理)を構築するため、サブクラスがそれらを定義していなくても、すべてのストリームインスタンスがこれらのメソッドをサポートします。実装メソッド(サブクラスでこれらをオーバーライドします):
- readinto(buf: bytearray) int | None¶
書き込み可能なバッファ buf にバイトを読み込みます。読み取ったバイト数を返します。ストリーム終端の場合は
0を、現時点で利用可能なデータがない場合(ノンブロッキングストリームの場合)はNoneを返します。
- write(buf: bytes) int | None¶
buf 内のバイトを書き込みます。書き込んだバイト数を返します。現時点で書き込みを実行できない場合(ノンブロッキングストリームの場合)は
Noneを返します。
- ioctl(request: int, arg: int) int¶
基盤となるストリーム/デバイスを制御します。request は
MP_STREAM_*リクエストコードのいずれかです。成功時には非負の値を、エラー時には負のerrno値を返します。
ストリームプロトコルメソッド(すべてのストリームインスタンスで利用可能):
- read(size: int = -1)¶
最大 size バイト(テキストモードでは文字)を読み取って返します。size が省略されたか負の場合は、ストリーム終端まで読み取ります。バイナリストリームでは
bytesを、テキストストリームではstrを返します。空の結果はストリーム終端を示します。
- readline(size: int = -1)¶
1 行を読み取って返します。末尾の改行文字が存在する場合はそれも含みます。size が指定された場合は、最大 size バイト(または文字)を読み取ります。ストリーム終端では空の
bytes/strを返します。
- close() None¶
ストリームを閉じ、基盤となるリソースを解放します。閉じられたストリームに対する操作は
OSError(メモリ内ストリームの場合はValueError)を送出します。
- seek(offset: int, whence: int = 0) int¶
現在のストリーム位置を whence を基準として offset バイトに変更します(
0= ストリーム先頭、1= 現在位置、2= ストリーム終端)。新しい絶対位置を返します。シーク不可能なストリームではOSErrorを送出します。
ストリームを直接反復処理すると、反復ごとに 1 行が生成されます。これは、空行というストリーム終端のセンチネルが返されるまでループ内で
readline()を呼び出すのと等価です。ストリームはコンテキストマネージャプロトコルもサポートしているため、with open(...) as f:を使うとストリームが自動的に閉じられます。注釈
MicroPython のストリームモジュールは、「1」のサフィックスが付いた C ヘルパー
mp_stream_read1_obj、mp_stream_readinto1_obj、mp_stream_write1_objも公開しています。これらは、リクエストが完全に満たされるまでループするのではなく、基盤となる I/O 呼び出しを 1 回だけ実行します。これらはmachine.UARTのようなクラスが独自のread/writeを実装するために内部的に使用されますが、標準のストリームクラスはこれらを Python から呼び出し可能なread1/readinto1/write1メソッドとしてバインドしていません。
- class io.StringIO(string: str = '')¶
テキストモードの入出力のためのメモリ内ファイルライクオブジェクトです("t" 修飾子で開いた通常のファイルに似ています)。初期内容は string パラメータ(通常の文字列であるべき)で指定できます。インスタンスはコンテキストマネージャプロトコルもサポートします(
with文で使用可能)。- seek(offset: int, whence: int = 0) int¶
ストリーム位置を whence を基準として offset に変更し(
0= 先頭、1= 現在、2= 終端)、新しい絶対位置を返します。
- close() None¶
ストリームを閉じ、基盤となるバッファを解放します。閉じられたストリームに対するそれ以降の操作は
ValueErrorを送出します。
- class io.StringIO(alloc_size: int)
最大 alloc_size バイトを保持できるよう事前割り当てされた空の
StringIOオブジェクトを作成します。これにより、そのバイト数までの書き込みではバッファの再割り当てが発生しません(メモリ不足の状況やメモリの断片化を回避します)。このコンストラクタは MicroPython の拡張であり、特殊なケースやシステムレベルのライブラリでのみ推奨され、エンドユーザー向けアプリケーションには推奨されません。CPython との違い
このコンストラクタは MicroPython の拡張です。
- seek(offset: int, whence: int = 0) int
ストリーム位置を whence を基準として offset に変更し(
0= 先頭、1= 現在、2= 終端)、新しい絶対位置を返します。
- tell() int
現在のストリーム位置を返します。
- flush() None
書き込みバッファをフラッシュします。メモリ内ストリームでは何もしません。
- close() None
ストリームを閉じ、基盤となるバッファを解放します。閉じられたストリームに対するそれ以降の操作は
ValueErrorを送出します。
- getvalue() str
基盤となるバッファの現在の内容を返します。
- class io.BytesIO(string: bytes = b'')¶
バイナリモードの入出力のためのメモリ内ファイルライクオブジェクトです("b" 修飾子で開いた通常のファイルに似ています)。初期内容は string パラメータ(bytes オブジェクトであるべき)で指定できます。インスタンスはコンテキストマネージャプロトコルもサポートします(
with文で使用可能)。- seek(offset: int, whence: int = 0) int¶
ストリーム位置を whence を基準として offset に変更し(
0= 先頭、1= 現在、2= 終端)、新しい絶対位置を返します。
- close() None¶
ストリームを閉じ、基盤となるバッファを解放します。閉じられたストリームに対するそれ以降の操作は
ValueErrorを送出します。
- class io.BytesIO(alloc_size: int)
最大 alloc_size バイトを保持できるよう事前割り当てされた空の
BytesIOオブジェクトを作成します。これにより、そのバイト数までの書き込みではバッファの再割り当てが発生しません(メモリ不足の状況やメモリの断片化を回避します)。このコンストラクタは MicroPython の拡張であり、特殊なケースやシステムレベルのライブラリでのみ推奨され、エンドユーザー向けアプリケーションには推奨されません。CPython との違い
このコンストラクタは MicroPython の拡張です。
- seek(offset: int, whence: int = 0) int
ストリーム位置を whence を基準として offset に変更し(
0= 先頭、1= 現在、2= 終端)、新しい絶対位置を返します。
- tell() int
現在のストリーム位置を返します。
- flush() None
書き込みバッファをフラッシュします。メモリ内ストリームでは何もしません。
- close() None
ストリームを閉じ、基盤となるバッファを解放します。閉じられたストリームに対するそれ以降の操作は
ValueErrorを送出します。
- getvalue() bytes
基盤となるバッファの現在の内容を返します。