2013-09-24 65 views
31

tôi nhận ra rằng khi tôi viết vào một tập tin sử dụng python nó đợi cho đến khi kết thúc của file Python của tôi để thực hiện nó:Python 2.7: Viết để nộp ngay lập tức

outputFile = open("./outputFile.txt","a") 
outputFile.write("First") 
print "Now you have 10sec to see that outputFile.txt is still the same as before" 
time.sleep(10) 
outputFile.write("Second") 
print "Now if you look at outputFile.txt you will see 'First' and 'Second'" 

Làm sao tôi cho rằng để làm cho python ghi ngay lập tức vào tập tin đầu ra?

Trả lời

47

Bạn có thể sử dụng flush() hoặc bạn có thể đặt đối tượng tệp thành không bị chặn.

Chi tiết về cách sử dụng thông số đó cho open()here.

Vì vậy, bạn sẽ thay đổi cuộc gọi đang mở để -

outputFile = open("./outputFile.txt", "a", 0) 
+2

Cảm ơn bạn, tùy chọn thứ hai là tốt nhất cho tôi bởi vì tôi không muốn viết outputFile.flush() mỗi lần nhưng cả hai đều hoạt động. – elbajo

+1

Thay vì để tệp mở trong các hoạt động chuyên sâu về thời gian, có thể đáng xem xét câu lệnh có thể thực hiện cùng một điều. – nachshon

+1

@nachshon "thực hiện cùng một điều": không cho tôi trên hệ thống của tôi (RHEL 6.8 với [conda] (https://en.wikipedia.org/wiki/Conda_ (package_manager)) dựa trên Python 2.7.13). Cuộc gọi 'os.fsync()' được đề cập trong câu trả lời của [ffeast] (https://stackoverflow.com/a/41506739/257924) là bắt buộc (không thể nói chắc chắn đối với Python dựa trên Microsoft Windows hoặc của hệ điều hành khác)). – bgoodr

14

Force nó với flush() chức năng, thêm

outputFile.flush() 

ở phần cuối của mã của bạn.

+2

Nếu mã được thêm vào ở cuối tập tin Python, không có gì được thực hiện mà sẽ không có được anyway khi tập tin được đóng lại. Thay vào đó, nó sẽ được thực hiện có thể nhiều lần - bất cứ khi nào nó muốn để đảm bảo tất cả các đầu ra được tạo ra cho đến nay được ghi vào tệp. – martineau

3

Như @RyPeck nói rằng bạn có thể sử dụng flush() hoặc thiết lập các đối tượng tập tin để được unbuffered. Nhưng lưu ý những điều sau đây (từ https://docs.python.org/2/library/stdtypes.html?highlight=file%20flush#file.flush):

Flush bộ đệm bên trong, giống như fflush stdio của().

Lưu ý flush() không nhất thiết phải ghi dữ liệu của tệp vào đĩa. Sử dụng flush() theo sau là os.fsync() để đảm bảo hành vi này.

Và một trích dẫn từ man 3 fflush:

Lưu ý rằng fflush() chỉ flushes bộ đệm sử dụng không gian được cung cấp bởi các thư viện C. Để đảm bảo rằng dữ liệu được lưu trữ trên đĩa vật lý, các bộ đệm hạt nhân cũng phải được xóa, ví dụ: với đồng bộ (2) hoặc fsync (2).

+0

Gọi os.fsync() tạm dừng mã của tôi ngay lập tức –

+0

@Nam 'os.fsync()' hoạt động hoàn hảo trên hệ thống của tôi (RHEL 6.8 với [conda] (https://en.wikipedia.org/wiki/Conda_ (package_manager))) - dựa trên Python 2.7.13). Bạn có chắc là bạn không có vấn đề về hệ thống tập tin hoặc hệ thống bị quá tải không? – bgoodr

+0

Tôi không biết. Tôi đang sử dụng Ubuntu Desktop 16 và Python 2.7 –

0

Chỉ cần để kết hợp tất cả các câu trả lời ở trên vào một tập hợp các chức năng tiện ích hữu ích vì một yêu cầu quan trọng của OP (và bản thân mình!) Là "because I don't want to write outputFile.flush() each time":

import os 
import tempfile 
import time 


def write_now(filep, msg): 
    """Write msg to the file given by filep, forcing the msg to be written to the filesystem immediately (now). 

    Without this, if you write to files, and then execute programs 
    that should read them, the files will not show up in the program 
    on disk. 
    """ 
    filep.write(msg) 
    filep.flush() 
    # The above call to flush is not enough to write it to disk *now*; 
    # according to https://stackoverflow.com/a/41506739/257924 we must 
    # also call fsync: 
    os.fsync(filep) 


def print_now(filep, msg): 
    """Call write_now with msg plus a newline.""" 
    write_now(filep, msg + '\n') 


# Example use with the with..as statement: 
with tempfile.NamedTemporaryFile(prefix='some_prefix_here.', suffix='.log', dir='.', delete=False) as logf: 
    print_now(logf, "this is a test1") 
    time.sleep(20) 
    print_now(logf, "this is a test2")