Почему файл не записывается до тех пор, пока я не остановлю программу?

Я запускаю тест и обнаружил, что файл фактически не записывается до тех пор, пока я не скрою -C, чтобы прервать программу. Может ли кто-нибудь объяснить, почему это произойдет?

Я ожидал, что он будет писать одновременно, поэтому я мог бы прочитать файл в середине процесса.

import os
from time import sleep

f = open("log.txt", "a+")
i = 0
while True:
  f.write(str(i))
  f.write("\n")
  i += 1
  sleep(0.1)

Ответ 1

Запись на диск медленная, поэтому многие программы сохраняют записи в большие куски, которые они пишут "все-в-одном". Это называется буферизацией, и Python делает это автоматически при открытии файла.

Когда вы пишете файл, вы на самом деле пишете "буфер" в памяти. Когда он заполняется, Python автоматически записывает его на диск. Вы можете сказать, что теперь "пишите все в буфере на диск" с помощью

f.flush()

Это не совсем так, потому что операционная система, вероятно, также будет записывать записи. Вы можете сказать, что он пишет буфер файла с

os.fsync(f.fileno())

Наконец, вы можете сказать Python не буферизовать конкретный файл с open(f, "w", 0) или только сохранить 1-строчный буфер с open(f,"w", 1). Естественно, это замедлит все операции над этим файлом, потому что записи идут медленно.

Ответ 2

Вам нужно f.close() чтобы f.close() буфер записи файла в файл. Или в вашем случае вы можете просто хотеть сделать f.flush(); os.fsync(); f.flush(); os.fsync(); поэтому вы можете продолжать цикл с открытым дескриптором файла.

Не забудьте import os.

Ответ 3

Вы захотите проверить file.flush() - хотя обратите внимание, что это может не записывать данные на диск, чтобы цитировать:

Примечание: flush() не обязательно записывает данные файлов на диск. Используйте flush(), за которым следует os.fsync(), чтобы обеспечить такое поведение.

Закрытие файла ( file.close()) также гарантирует, что данные записаны - использование with будет делать это неявно и, как правило, лучший выбор для большей удобочитаемости и ясности - не говоря уже о решении других потенциальных проблем.

Ответ 4

Вы должны заставить писать, поэтому я использую следующие строки, чтобы убедиться, что файл написан:

# Two commands together force the OS to store the file buffer to disc
    f.flush()
    os.fsync(f.fileno())

Ответ 5

Это оконный вид. Если вы добавите явное .close() когда закончите с файлом, оно появится в проводнике в то время. Даже просто промывать его может быть достаточно (у меня нет окна, пригодного для тестирования). Но в основном f.write на самом деле не пишет, он просто присоединяется к буферу записи - пока буфер не покраснет, вы его не увидите.

В unix файлы обычно отображаются в виде 0-байтового файла в этой ситуации.

Ответ 6

Обработчик файлов для очистки.

f.flush()

Ответ 7

Файл не записывается, поскольку выходной буфер не очищается до тех пор, пока сбор мусора не вступит в силу, и f.close() буфер ввода-вывода (более чем вероятно, вызвав f.close()).

Альтернативно, в вашем цикле вы можете вызвать f.flush() а затем os.fsync(), как os.fsync() здесь.

f.flush()
os.fsync()

Все, что было сказано, если вы когда-либо планируете делиться данными в этом файле с другими частями вашего кода, я настоятельно рекомендую использовать объект StringIO.