少なくとも行に文字を挿入したい場合は、ファイルをその場で変更することはできません。次の行の先頭を上書きしてしまうだけです。
これを行うには、次の 2 つの方法があります。
- ファイルをメモリに読み込み、閉じてから、新しいバージョンを書き戻します。
- 作業を進めながら新しい一時ファイルを作成し、それを元のバージョンに移動します。
では、それらの中からどのように選択しますか?重要な場合は、それぞれが通常以下のものよりも優先されるように並べ替えて、違いを要約しようとします (ただし、これは「通常」にすぎません。独自のユース ケースを検討する必要があります)。
2 では、全体をメモリに保持する必要はありません。たとえば、ファイルの長さが 20 GB の場合、これは明らかに大きなメリットです。16KBなら問題ありません。
2 は操作全体をアトミックにします。途中で失敗したり、変更中に他のプロセスがファイルを読み込もうとしたりしても、途中で変更された無効なファイルを誰かが見ることはできません。元のファイルまたは新しいファイルのいずれかが表示されます。
2 には、ある程度の空きディスク容量が必要です (一時的にファイルの 2 つのコピーが同時に存在するため)。
2 は、Windows と POSIX の両方に関心がある場合、首の大きな痛みです。
注意しない限り、元のファイルと一時ディレクトリが異なるファイルシステムにある場合、ファイルシステム間でのコピーが必要になる可能性があります。
上記の 2 つのどちらも問題にならない場合は、2 の方が簡単です。
Drakekin's answer は、#1 のやり方を教えてくれます。
Windows やクロスファイルシステムの問題を気にしない場合の #2 の実行方法は次のとおりです。
infile = open("cache.ucb", 'rb')
outfile = tempfile.NamedTemporaryFile(delete=False)
for line in infile:
if line.split('~!')[0] == ex[4]:
line += "~!" + mask[0]
line = line.rstrip() + "\n"
outfile.write(line)
infile.close()
os.rename(outfile.name, "cache.ucb")
outfile.close()
dir=os.path.dirname(original path)
たとえば、コンストラクターに渡すことでクロスファイルシステムの問題を解決できNamedTemporaryFile
ますが、元のファイルと一緒に新しいファイルを作成する権限を常に持っていることが確実な場合に限ります (常に保証されているわけではありません。オリジナルを書き換えるパーミッション — UNIX パーミッション、Windows ACL、OS X サンドボックスなどはすべて、false になる可能性のある方法を提供します)。
Windows の問題を解決するには、まずIs anatomic file rename (with overwrite) possible on Windowsから始め、同様の議論がインターネット上で行われています。