파이썬은 파일을 얼마나 자주 플러시합니까?


228
  1. 파이썬은 파일을 얼마나 자주 플러시합니까?
  2. 파이썬은 얼마나 자주 stdout으로 플러시합니까?

확실하지 않습니다 (1).

(2)에 관해서는, 매 줄마다 파이썬이 stdout으로 플러시한다고 생각합니다. 그러나 stdout에 파일이되도록 과부하하면 자주 플러시됩니까?

답변:


332

파일 작업의 경우 Python은 달리 구성하지 않는 한 운영 체제의 기본 버퍼링을 사용합니다. 버퍼 크기, 버퍼링되지 않은 또는 라인 버퍼링을 지정할 수 있습니다.

예를 들어, open 함수는 버퍼 크기 인수를 사용합니다.

http://docs.python.org/library/functions.html#open

"선택적 버퍼링 인수는 파일의 원하는 버퍼 크기를 지정합니다."

  • 0은 버퍼되지 않음을 의미하고
  • 1은 라인 버퍼링을 의미하고
  • 다른 양수 값은 해당 크기의 버퍼를 사용한다는 것을 의미합니다.
  • 네거티브 버퍼링은 시스템 기본값을 사용하는 것을 의미합니다. 일반적으로 tty 장치의 경우 라인 버퍼링되고 다른 파일의 경우 완전히 버퍼링됩니다.
  • 생략하면 시스템 기본값이 사용됩니다.

암호:

bufsize = 0
f = open('file.txt', 'w', buffering=bufsize)

23
"라인 버퍼링 된"부분의 경우 +1 그것이 바로 내가 찾던 것이었고 매력처럼 작동합니다.
33 분

2
open('file.txt', 'w', 1)적절한 라인 버퍼링을 얻을 때 Python 3.4.3을 사용 합니다. 그러나 내가 더 큰 일을 원한다면 (여기서 원했던 open('file.txt', 'w', 512)) io.DEFAULT_BUFFER_SIZE8192 전체 를 버퍼링합니다 . 파이썬 버그, 리눅스 버그 또는 ID10t 버그입니까?
Bruno Bronosky

이미 열린 스트림 의 버퍼링을 변경할 수 있습니까? 말, 내가 원하는 stdout라인 버퍼에 관계없이 콘솔 여부 또는 파일로 리디렉션?
Mikhail T.

1
@CharlieParker write()파일 핸들 을 호출 하면 출력이 메모리에 버퍼링되고 버퍼가 가득 찰 때까지 누적됩니다. 버퍼가 "플러시"될 때 (버퍼에서 파일로 내용이 기록됨) flush()파일 핸들 에서 메소드를 호출하여 명시 적으로 버퍼를 플러시 할 수 있습니다 .
Corey Goldberg

3
버퍼링되지 않은 (0)은 바이너리 모드에서만 사용할 수 있으며 라인 버퍼링 된 (1)은 텍스트 모드에서만 사용할 수 있습니다.
ZaydH

172

flush()메소드를 사용하여 프로그래밍 방식으로 버퍼를 파일로 강제 플러시 할 수도 있습니다 .

with open('out.log', 'w+') as f:
    f.write('output is ')
    # some work
    s = 'OK.'
    f.write(s)
    f.write('\n')
    f.flush()
    # some other work
    f.write('done\n')
    f.flush()

출력 파일에 꼬리를 달 때 유용하다는 것을 알았습니다 tail -f.


54
문서에서 :Note: flush() does not necessarily write the file’s data to disk. Use flush() followed by os.fsync() to ensure this behavior.
bobismijnnaam

1
@bobismijnnaam은 다음 번에 해당 문서에 링크했습니다. 내가 찾을 수있는 참조 만 github.com/jprzywoski/python-reference/blob/master/source/docs/ 에서 왔으며 누구인지 모릅니다.
Bruno Bronosky

5
@Bruno Bronosky 좋은 지적입니다. 문서 : Note: flush() does not necessarily write the file’s data to disk. Use flush() followed by os.fsync() to ensure this behavior.
bobismijnnaam

내가 혼동하는 것은 그 용어 flushing가 의미하는 것입니다. 왜 필요한가요? 무엇입니까? 왜 내가 신경 써야합니까?
Charlie Parker

@CharlieParker를 쓸 때 RAM에있는 파일의 일부 (일부)에 쓰면 잠시 동안 디스크에 저장되지 않을 수 있습니다. 성능은 향상되지만 사본이 작성되지 않은 경우 (디스크 제거, OS 충돌 등) 데이터가 손실 될 수 있습니다. flush ()는 파이썬에게 즉시 그 버퍼를 디스크에 다시 쓰도록 지시합니다. (os.fsync ()는 OS에게도 그렇게하도록 지시합니다. 많은 버퍼 레이어가 있습니다 ...)
Rena

13

이것이 파이썬에도 적용되는지는 모르겠지만 실행중인 운영 체제에 달려 있다고 생각합니다.

예를 들어 Linux에서 터미널로의 출력은 개행에서 버퍼를 플러시하는 반면 파일로 출력하는 경우 버퍼가 가득 찼을 때만 기본적으로 플러시됩니다. 버퍼를 더 적은 시간에 플러시하는 것이 더 효율적이고 출력이 파일의 개행에서 플러시되지 않는 경우 사용자가 알아 차리지 못할 수 있기 때문입니다.

필요한 경우 출력을 자동 플러시 할 수 있습니다.

편집 : 나는 당신이 이런 식으로 파이썬에서 자동 플러시 할 것이라고 생각합니다 ( 여기 부터 )

#0 means there is no buffer, so all output
#will be auto-flushed
fsock = open('out.log', 'w', 0)
sys.stdout = fsock
#do whatever
fsock.close()

12

io 모듈에서 읽기 전용 DEFAULT_BUFFER_SIZE 속성을 호출하여 기본 버퍼 크기를 확인할 수도 있습니다.

import io
print (io.DEFAULT_BUFFER_SIZE)

1
감사! 파이썬이 OS가 정의한대로 설정 한다는 것을 아는 것이 좋지만 이것은 OS가 사전 정의한 것을 찾는 데 도움이됩니다 .
Cometsong

2

여기에 OP를 선택하여 원하는 것을 선택하는 또 다른 접근법이 있습니다.

__init__다른 코드보다 먼저 .py 파일에 아래 코드를 포함 시키면 인쇄 된 메시지와 print오류가 더 이상 Ableton의 Log.txt에 기록되지 않고 디스크의 파일을 분리합니다.

import sys

path = "/Users/#username#"

errorLog = open(path + "/stderr.txt", "w", 1)
errorLog.write("---Starting Error Log---\n")
sys.stderr = errorLog
stdoutLog = open(path + "/stdout.txt", "w", 1)
stdoutLog.write("---Starting Standard Out Log---\n")
sys.stdout = stdoutLog

(Mac의 경우 #username#사용자 폴더 이름으로 변경 합니다. Windows에서는 사용자 폴더 경로의 형식이 다릅니다)

디스크의 파일이 변경 될 때 내용을 새로 고치는 텍스트 편집기에서 파일을 열면 (예 : Mac의 경우 : TextEdit가 아니라 TextWrangler가 수행함) 로그가 실시간으로 업데이트되는 것을 볼 수 있습니다.

크레딧 :이 코드는 대부분 Nathan Ramella에 의해 liveAPI 컨트롤 스크립트에서 복사되었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.