Pythonでファイルを読み取り、上書きする


108

現在私はこれを使っています:

f = open(filename, 'r+')
text = f.read()
text = re.sub('foobar', 'bar', text)
f.seek(0)
f.write(text)
f.close()

しかし問題は、古いファイルが新しいファイルよりも大きいことです。そのため、最後に古いファイルの一部が含まれる新しいファイルが作成されます。

回答:


178

ファイルを閉じて再度開きたくない場合は、競合状態を回避するために、次のようにtruncateします。

f = open(filename, 'r+')
text = f.read()
text = re.sub('foobar', 'bar', text)
f.seek(0)
f.write(text)
f.truncate()
f.close()

エラーが発生した場合でも、ファイルハンドラーを閉じるコンテキストマネージャーとして使用すると、機能はよりクリーンで安全openになります。

with open(filename, 'r+') as f:
    text = f.read()
    text = re.sub('foobar', 'bar', text)
    f.seek(0)
    f.write(text)
    f.truncate()

念のためf.write(text)f.truncate()言っておきますが、2番目のクリップは後にする必要がありますか?
volvox 2019

2
このコードでf.write(text)は@volvox が前f.truncate()にあります。text最初に書き込むため.write()、ファイルカーソルがの末尾に配置されますtext。ファイルの切り捨てを続行すると、この時点以降にファイルに残っている可能性のあるバイトがすべて削除されます。この場合、最終的な結果は、書き込む前に切り捨てた場合と同じになります。
nosklo

非常に大きなファイルの場合、ファイルの内容全体をメモリに読み込むと扱いにくくなることがあります。したがって、fileinputモジュールは推奨される方法になります。渡されるとinplace=1、最初にファイルを一時的な場所に移動し、次に新しいファイルを古いファイル名のパスに書き込みます。この移動操作はinode、完全なコンテンツではなくファイルシステムを移動するだけなので、UNIXファイルシステムでは高速です。次に、メモリの膨張を回避するために、各行を個別に読み取って処理できます。:-)
TrinitronX

16

おそらく、の後text = re.sub('foobar', 'bar', text)でファイルを閉じ、書き込み用に再度開いて(古い内容を消去して)、更新したテキストをファイルに書き込む方が簡単で簡潔です。


16

fileinputモジュールがいるinlineなど、あなたが一時ファイルを使用せずに処理しているファイルにモジュールを変更を記述するためのモードがうまく透過的にファイル名を追跡したオブジェクトを経由して、ファイルのリスト内の行をループの一般的な操作をカプセル化し、ループ内で検査したい場合は、行番号など。

import fileinput
for line in fileinput.FileInput("file",inplace=1):
    if "foobar" in line:
         line=line.replace("foobar","bar")
    print line

0

正直に言うと、基本的なファイル操作を行う、私が作成したこのクラスを見ることができます。writeメソッドは古いデータを上書きして追加します。

class IO:
    def read(self, filename):
        toRead = open(filename, "rb")

        out = toRead.read()
        toRead.close()
        
        return out
    
    def write(self, filename, data):
        toWrite = open(filename, "wb")

        out = toWrite.write(data)
        toWrite.close()

    def append(self, filename, data):
        append = self.read(filename)
        self.write(filename, append+data)
        

-2

新しいファイルに書き込んでください。

f = open(filename, 'r+')
f2= open(filename2,'a+')
text = f.read()
text = re.sub('foobar', 'bar', text)
f.seek(0)
f.close()
f2.write(text)
fw.close()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.