0

Python でテキスト ファイルをその場で編集しようとしています。非常に大きいため、メモリにロードすることはできません。内部で見つけたバイト単位の文字列を置き換えるつもりです。

with f as open("filename.txt", "r+b"):
    if f.read(8) == "01234567":
        f.seek(-8, 1)
        f.write("87654321")

ただし、試してみると、 write() 操作がファイルの末尾に追加されます。

>>> n.read()
'sdf'
>>> n.read(1)
''
>>> n.seek(0,0)
>>> n.read(1)
's'
>>> n.read(1)
'd'
>>> n.write("sdf")
>>> n.read(1)
''
>>> n.seek(0,0)
>>> n.read()
'sdfsdf'
`

その結果を にしたいsdsdf

4

2 に答える 2

1

元の ANSI / ISO C 規格では、読み書きモード ストリームを読み取りモードから書き込みモードに、またはその逆に切り替えるときに、シーク操作が必要でした。この制限は存続します。たとえば、n1570には次のテキストが含まれます。

ファイルが更新モード ('+'上記のモード引数値のリストの 2 番目または 3 番目の文字) で開かれると、関連するストリームで入力と出力の両方が実行される場合があります。ただし、fflush関数またはファイル配置関数 ( fseekfsetpos、またはrewind) への呼び出しが介在することなく、出力の直後に入力が続くことはありません。入力操作でファイルの終わりが検出されました。一部の実装では、更新モードでテキスト ファイルを開く (または作成する) と、代わりにバイナリ ストリームを開く (または作成する) 場合があります。

なんらかの理由で、この制限は Python にインポートされました。1 Python ラッパーが自動的に処理することは可能ですが。

元の ANSI C の制限の理由は、多くの Unix ベースのシステムで見られる低予算の実装でした。それらは、ストリームごとに、「現在のバイト数」と「現在のポインター」を保持していました。マクロ化さgetcputcた操作が基になる実装を呼び出す必要がある場合、現在のバイト数は 0 でした。これにより、ストリームが更新モードで開かれているかどうかを確認し、必要に応じて切り替えることができます。ただし、文字の取得に成功すると、カウンターは基になるストリームから引き続き読み取ることができる文字数を保持します。文字の書き込みに成功すると、カウンターは文字の追加を許可するバッファー位置の数を保持します。

getcこれは、内部バッファを埋めることに成功したが、その後に が続く場合putc、 からの「書き込まれた」文字putcがバッファリングされたデータを単純に上書きすることを意味していました。成功しputcたが、実装が不十分な が続いた場合getc、バッファから未設定の値が表示されます。

この問題は簡単に修正できました (入力カウンターと出力カウンターを別々に用意し、そのうちの 1 つが常に 0 になるようにし、モード スイッチのバッファー補充チェックを実装する関数も用意するだけです)。


1引用が必要です :-)

于 2015-11-01T00:41:15.357 に答える