Đọc và ghi đè tệp bằng Python


108

Hiện tại tôi đang sử dụng cái này:

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

Nhưng vấn đề là tệp cũ lớn hơn tệp mới. Vì vậy, tôi kết thúc với một tệp mới có một phần của tệp cũ ở cuối nó.

Câu trả lời:


178

Nếu bạn không muốn đóng và mở lại tệp, để tránh các điều kiện về chủng tộc, bạn có thể truncate:

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

Chức năng này cũng có thể sẽ sạch hơn và an toàn hơnopen khi sử dụng làm trình quản lý ngữ cảnh, chức năng này sẽ đóng trình xử lý tệp, ngay cả khi xảy ra lỗi!

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

Tôi chỉ cần rõ ràng trong đầu - clip thứ hai của bạn nên có f.write(text)sau f.truncate()?
volvox

2
@volvox f.write(text)nằm trước f.truncate()trong mã này; nó ghi textđầu tiên, vì vậy sau khi .write()con trỏ tệp được đặt ở cuối text. Tiến hành cắt bớt tệp sẽ loại bỏ bất kỳ byte nào còn lại mà tệp có thể có sau thời điểm này. Trong trường hợp này, kết quả cuối cùng sẽ giống như khi bạn cắt ngắn trước khi viết.
nosklo

Đối với các tệp rất lớn, việc đọc toàn bộ nội dung tệp vào bộ nhớ có thể trở nên khó sử dụng. Do đó, fileinputmô-đun có thể trở thành phương pháp được ưu tiên. Khi được thông qua inplace=1, nó sẽ di chuyển tệp đến vị trí tạm thời trước tiên, sau đó ghi tệp mới vào đường dẫn tên tệp cũ. Thao tác di chuyển này diễn ra nhanh trên hệ thống tệp unix, vì nó chỉ di chuyển hệ thống tệp inodechứ không phải toàn bộ nội dung. Sau đó, bạn có thể đọc và xử lý từng dòng riêng lẻ để tránh bộ nhớ bị phình ra. :-)
TrinitronX

16

Có lẽ sẽ dễ dàng hơn và gọn gàng hơn khi đóng tệp text = re.sub('foobar', 'bar', text), mở lại để viết (do đó xóa nội dung cũ) và viết văn bản cập nhật của bạn vào đó.


16

Các fileinputmô-đun có inlinechế độ cho các văn bản thay đổi đối với tập tin bạn đang xử lý mà không sử dụng tập tin tạm thời, vv Các module độc đáo gói gọn các hoạt động chung của Looping trên các dòng trong một danh sách các tập tin, thông qua một đối tượng mà minh bạch theo dõi những tên tập tin, số dòng, v.v. nếu bạn muốn kiểm tra chúng bên trong vòng lặp.

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

0

Thành thật mà nói, bạn có thể xem lớp này mà tôi đã xây dựng, nó thực hiện các thao tác cơ bản với tệp. Phương thức ghi sẽ ghi đè và chắp thêm giữ dữ liệu cũ.

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

Hãy thử ghi nó vào một tệp mới ..

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()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.