2013-07-15 36 views
6

Mục đích của tôi là đọc dòng từ tệp, bỏ trống khoảng trống ở cuối tệp và ghi lại vào cùng một tệp. Tôi đã thử các mã sau:viết lại vào cùng một tệp tin sau khi đọc từ tập tin

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

Điều này dường như viết ở cuối tệp, giữ nguyên dữ liệu ban đầu trong tệp. Tôi biết rằng bằng cách sử dụng f.seek(0) sẽ đưa con trỏ trở lại để bắt đầu của tập tin, mà tôi giả định sẽ được bằng cách nào đó cần thiết cho giải pháp này.

Bạn có thể vui lòng thông báo nếu có cách tiếp cận khác cho điều này hoặc tôi trên bản vá đúng chỉ cần thêm nhiều logic hơn vào mã không?

Trả lời

5

Sử dụng một tập tin tạm thời. Python cung cấp các tiện ích để tạo các tệp tạm thời một cách an toàn. Gọi ví dụ dưới đây với: 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]) 

Tài liệu tham khảo ở đây: http://docs.python.org/2/library/tempfile.html

+0

Ví dụ hay và giải thích tuyệt vời. – misguided

+0

Cảm ơn. Tôi thích sử dụng các tệp tạm thời ngay cả khi bộ nhớ có sẵn. Ngoài ra kiểm tra các tập tin tạm thời spooled trong các tài liệu tempfile, trong đó cung cấp cho một thỏa hiệp thú vị. – JonnyRo

1

Vấn đề với cách tiếp cận của bạn là bạn cần cả luồng đầu vào và luồng đầu ra, có thể trỏ đến các vị trí khác nhau trong cùng một tệp. Nếu bạn muốn sử dụng f.seek() thì bạn sẽ cần lưu trữ vị trí bằng cách sử dụng f.tell() sau mỗi lần đọc và viết. Ví dụ:

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) 

Nhưng điều đó gây nhầm lẫn và dễ bị lỗi. Nếu tập tin không phải là quá lớn, tại sao không đọc tất cả vào bộ nhớ và sau đó viết nó trở lại một lần nữa?

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

Nếu tập tin là quá lớn để phù hợp với bộ nhớ, sau đó viết các dòng vào một tập tin tạm thời và sau đó đổi tên các tập tin khi bạn đang thực hiện:

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

giải pháp cuối cùng của bạn dường như gần như giải quyết vấn đề này, các con chỉ còn lại vấn đề, tôi muốn tên tập tin mới để thay đổi tức là, tệp mới sẽ thay thế tệp cũ. Nếu tôi thực hiện nó theo phương pháp được chỉ định ở trên, tôi nhận được 'WindowsError: [Lỗi 183] Không thể tạo tệp khi tệp đó đã tồn tại' – misguided

+1

Thật dễ dàng, chỉ cần xóa tệp cũ sau khi đóng nó nhưng trước khi đổi tên:' os.remove (tên tệp) ' –

Các vấn đề liên quan