2013-07-15 14 views
6

私の目的は、ファイルから行を読み込み、最後に空白を取り除いて同じファイルに書き戻すことです。私は次のコードを試しました:ファイルから読み込んだ後に同じファイルに書き戻す

with open(filename, 'r+') as f: 
    for i in f: 
     f.write(i.rstrip()+"\n") 

これは、ファイルの最初のデータをそのまま残しておくようです。 f.seek(0)を使用すると、ファイルの先頭にポインタが戻ってくることがわかります。これは、この解決策のために必要と思われるものです。

これに対して別の方法があるのか​​アドバイスしてもらえますか?正しいパッチでコードにロジックを追加するだけですか?

答えて

5

は、一時ファイルを使用してください。 Pythonは、一時的なファイルを安全に作成するための機能を提供します。して以下の例を呼び出します:python modify.pyのtarget_filename

import tempfile 
import sys 

def modify_file(filename): 

     #Create temporary file read/write 
     t = tempfile.NamedTemporaryFile(mode="r+") 

     #Open input file read-only 
     i = open(filename, 'r') 

     #Copy input file to temporary file, modifying as we go 
     for line in i: 
      t.write(line.rstrip()+"\n") 

     i.close() #Close input file 

     t.seek(0) #Rewind temporary file to beginning 

     o = open(filename, "w") #Reopen input file writable 

     #Overwriting original file with temporary file contents   
     for line in t: 
      o.write(line) 

     t.close() #Close temporary file, will cause it to be deleted 

if __name__ == "__main__": 
     modify_file(sys.argv[1]) 

参考資料ここでは http://docs.python.org/2/library/tempfile.html

+0

いい例と素晴らしい説明。 – misguided

+0

ありがとうございます。メモリが利用可能であっても一時ファイルを使用するのが好きです。また、一時ファイルdocs内のスプールされた一時ファイルをチェックしてください。これは面白い妥協点を示しています。 – JonnyRo

1

あなたのアプローチの問題は、入力ストリームと出力ストリームの両方が必要であることです。入力ストリームと出力ストリームは、同じファイル内の別の場所を指すことができます。 f.seek()を使用する場合は、それぞれの読み取りと書き込みの後にf.tell()を使用して位置を保存する必要があります。例:

f = open(filename, 'r+') 
while True: 
    i = f.readline() 
    if i == '': break 
    in = f.tell() 
    f.seek(out) 
    f.write(i.rstrip()+"\n") 
    out = f.tell() 
    f.seek(in) 

これは混乱しやすく、エラーが発生する可能性があります。ファイルが大きすぎない場合は、すべてをメモリに読み込んでから、再度書き戻してみてください。

in = open(filename, 'r') 
lines = in.read() 
in.close() 
out = open(filename, 'w') 
out.write([line.rstrip()+'\n' for line in lines.split('\n')]) 
out.close() 

ファイルは、一時ファイルに行を書き込み、その後、作業が完了したときにファイル名を変更し、メモリに収まる大きすぎる場合:

out = open(filename+'.tmp', 'w') 
with open(filename, 'r') as f: 
    for i in f: 
     out.write(i.rstrip()+"\n") 
out.close() 
os.rename(filename+'.tmp', filename) 
+0

あなたの最後の解決策は、唯一の問題残りは、私は新しいファイル名を変更したいほとんどの問題を解決しているようですすなわち、新しいファイルは古いファイルを置き換えるはずです。上記の方法でそれを行うと、 'WindowsError:[エラー183]そのファイルが既に存在するときにファイルを作成できない' – misguided

+1

簡単なことですが、古いファイルを閉じた後、名前を変更する前に削除してください: 'os.remove (ファイル名) ' –