2013-07-15 6 views
6

Mein Ziel ist es, Zeile aus der Datei zu lesen, entfernen Sie die Leerzeichen am Ende und schreiben Sie zurück in die gleiche Datei. Ich habe den folgenden Code ausprobiert:zurück in die gleiche Datei schreiben nach dem Lesen aus der Datei

Dies scheint am Ende der Datei zu schreiben, erste Daten in der Datei intakt zu halten. Ich weiß, dass die Verwendung von f.seek(0) den Zeiger zurück zum Anfang der Datei bringen würde, von dem ich annehme, dass es für diese Lösung irgendwie erforderlich sein würde.

Können Sie bitte beraten, ob es einen anderen Ansatz dafür gibt oder bin ich auf der rechten Seite muss nur mehr Logik in den Code hinzufügen?

Antwort

5

eine temporäre Datei verwenden. Python bietet Funktionen zum sicheren Erstellen temporärer Dateien. Rufen Sie folgende Beispiel mit: 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]) 

Referenzen hier: http://docs.python.org/2/library/tempfile.html

+0

Schönes Beispiel und großartige Erklärung. – misguided

+0

Danke. Ich verwende gerne temporäre Dateien, selbst wenn Speicher verfügbar ist. Überprüfen Sie auch die gespoolte temporäre Datei in den temporären Dateien, die einen interessanten Kompromiss darstellt. – JonnyRo

1

Das Problem mit Ihrem Ansatz besteht darin, dass Sie sowohl einen Eingabestream als auch einen Ausgabestream benötigen, der auf verschiedene Stellen in derselben Datei zeigen kann. Wenn Sie f.seek() verwenden möchten, müssen Sie die Position nach jedem Lesen und Schreiben mit f.tell() speichern. Zum Beispiel:

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) 

Aber das ist verwirrend und fehleranfällig. Wenn die Datei nicht zu groß ist, warum sollte sie nicht alles in den Speicher gelesen und dann wieder zurückgeschrieben werden?

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() 

Wenn die Datei zu groß ist, in den Speicher zu passen, dann die Zeilen in eine temporäre Datei schreiben und dann die Datei umbenennen, wenn Sie fertig sind:

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

Ihre letzte Lösung, das Problem zu lösen fast scheint, das einzige Problem verbleibende Wesen, ich möchte, dass die neuen Dateinamen ändern dh die neue Datei sollte die alte Datei ersetzen. Wenn ich es mit der oben angegebenen Methode mache, bekomme ich 'WindowsError: [Error 183] Kann keine Datei erstellen, wenn diese Datei bereits existiert' – misguided

+1

Das ist einfach, entferne einfach die alte Datei nach dem Schließen, aber vor dem Umbenennen:' os.remove (Dateiname) ' –

Verwandte Themen