Почему файл не записывается до тех пор, пока я не остановлю программу?
Я запускаю тест и обнаружил, что файл фактически не записывается до тех пор, пока я не скрою -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
.