3

PHP コードを Python に変換しようとしていますが、行の置換に問題があります。Python を使用する方が簡単だと思いますが、完全に迷っています。置換する行を見つけることはできます。行の最後に何かを追加することはできますが、その行をファイルに再度書き込むことはできません。

file = open("cache.ucb", 'rb')
for line in file:
   if line.split('~!')[0] == ex[4]:
       line += "~!" + mask[0]
       line = line.rstrip() + "\n"
       # Write on the file here!

基本的に、ファイル~!はセパレーターとして使用され、各行を読み取ります。行の で区切られた最初のトークン~!が で始まるex[4]場合、たとえば の場合、その行の最後にをCatbuntu追加します。次に改行文字を削除し、末尾に 1 つ追加します。mask[0]Bousie

そして、問題があります。ファイルをそのまま書きたいのですが、その行だけを変更します。それは可能ですか?

4

4 に答える 4

2

少なくとも行に文字を挿入したい場合は、ファイルをその場で変更することはできません。次の行の先頭を上書きしてしまうだけです。

これを行うには、次の 2 つの方法があります。

  1. ファイルをメモリに読み込み、閉じてから、新しいバージョンを書き戻します。
  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から始め、同様の議論がインターネット上で行われています。

于 2012-12-21T21:11:36.960 に答える
1

ファイルをモード「wb」で開き、file.write(line)ループの最後に置きます。

于 2012-12-21T20:51:07.283 に答える
0

ファイルを書き込み用に開いていません。

file = open("cache.ucb", 'rb')

この行は、バイナリ モードで読み取るファイルを開きます。書き込み用にも開く必要があります。

ファイルを書き込みモード 'w' で開き、行を書き戻してみてください。

または、最初に読み取り/書き込み用にファイルを開き、ループ内に書き込むこともできます。

file = open("cache.ucb", 'a+')
于 2012-12-21T20:50:52.697 に答える