元の ANSI / ISO C 規格では、読み書きモード ストリームを読み取りモードから書き込みモードに、またはその逆に切り替えるときに、シーク操作が必要でした。この制限は存続します。たとえば、n1570には次のテキストが含まれます。
ファイルが更新モード ('+'
上記のモード引数値のリストの 2 番目または 3 番目の文字) で開かれると、関連するストリームで入力と出力の両方が実行される場合があります。ただし、fflush
関数またはファイル配置関数 ( fseek
、fsetpos
、またはrewind
) への呼び出しが介在することなく、出力の直後に入力が続くことはありません。入力操作でファイルの終わりが検出されました。一部の実装では、更新モードでテキスト ファイルを開く (または作成する) と、代わりにバイナリ ストリームを開く (または作成する) 場合があります。
なんらかの理由で、この制限は Python にインポートされました。1 Python ラッパーが自動的に処理することは可能ですが。
元の ANSI C の制限の理由は、多くの Unix ベースのシステムで見られる低予算の実装でした。それらは、ストリームごとに、「現在のバイト数」と「現在のポインター」を保持していました。マクロ化さgetc
れputc
た操作が基になる実装を呼び出す必要がある場合、現在のバイト数は 0 でした。これにより、ストリームが更新モードで開かれているかどうかを確認し、必要に応じて切り替えることができます。ただし、文字の取得に成功すると、カウンターは基になるストリームから引き続き読み取ることができる文字数を保持します。文字の書き込みに成功すると、カウンターは文字の追加を許可するバッファー位置の数を保持します。
getc
これは、内部バッファを埋めることに成功したが、その後に が続く場合putc
、 からの「書き込まれた」文字putc
がバッファリングされたデータを単純に上書きすることを意味していました。成功しputc
たが、実装が不十分な が続いた場合getc
、バッファから未設定の値が表示されます。
この問題は簡単に修正できました (入力カウンターと出力カウンターを別々に用意し、そのうちの 1 つが常に 0 になるようにし、モード スイッチのバッファー補充チェックを実装する関数も用意するだけです)。
1引用が必要です :-)