Python'da bir dosyayı okuyun ve üzerine yazın


108

Şu anda bunu kullanıyorum:

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

Ancak sorun, eski dosyanın yeni dosyadan daha büyük olmasıdır. Bu yüzden sonunda eski dosyanın bir parçası olan yeni bir dosya buluyorum.

Yanıtlar:


178

Yarış koşullarından kaçınmak için dosyayı kapatıp yeniden açmak istemiyorsanız şunları yapabilirsiniz truncate:

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

İşlevsellik, bir hata oluşsa bile dosya işleyicisini kapatan bir bağlam yöneticisi olarak kullanıldığında büyük olasılıkla daha temiz ve daha güvenliopen olacaktır!

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

Sadece aklımda net olmak gerekirse - ikinci klibin f.write(text)sonrası olmalı f.truncate()mı?
volvox

2
@volvox bu kodda f.write(text)önce gelir f.truncate(); textilkini yazar , bu yüzden .write()dosya imleci sonuna yerleştirildikten sonra text. Dosyayı kesmeye devam etmek, dosyanın bu noktadan sonra sahip olabileceği kalan baytları kaldıracaktır. Bu durumda, sonuç, yazmadan önce kısaltmanızla aynı olacaktır.
nosklo

Çok büyük dosyalar için, tüm dosya içeriğini belleğe okumak zor olabilir. Bu nedenle fileinputmodül tercih edilen yöntem haline gelebilir. Geçildiğinde inplace=1, dosyayı önce geçici bir konuma taşıyacak, ardından eski dosya adı yoluna yeni bir dosya yazacaktır. Bu taşıma işlemi, unix dosya sistemlerinde hızlıdır, çünkü inodetüm içeriği değil, sadece dosya sistemini taşır . Ardından, bellek şişkinliğini önlemek için her satırı ayrı ayrı okuyabilir ve işleyebilirsiniz. :-)
TrinitronX

16

Muhtemelen daha sonra dosyayı kapatmak, text = re.sub('foobar', 'bar', text)yazmak için yeniden açmak (böylece eski içerikleri temizlemek) ve güncellenmiş metninizi yazmak daha kolay ve düzenli olacaktır .


16

fileinputModülü vardır inline, şeffaf dosya adının izler bir nesne aracılığıyla, modül güzel dosyaların listesini satırların üzerinde döngü ortak çalışmasını kapsüller geçici dosyaları kullanmadan vb olmadan işliyoruz dosyada değişiklik yazmak için modu döngü içinde incelemek isterseniz satır numarası vb.

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

0

Dürüst olmak gerekirse, temel dosya işlemlerini yapan, oluşturduğum bu sınıfa bir göz atabilirsiniz. Yazma yöntemi üzerine yazar ve ekleme, eski verileri korur.

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

Yeni bir dosyaya yazmayı deneyin ..

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()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.