Обычно используется два уровня буферизации:
- Внутренние буферы
- Буферы операционной системы
Внутренние буферы - это буферы, создаваемые средой выполнения / библиотекой / языком, для которых вы программируете, и призваны ускорить процесс, избегая системных вызовов для каждой записи. Вместо этого, когда вы записываете в файловый объект, вы записываете в его буфер, и всякий раз, когда буфер заполняется, данные записываются в реальный файл с использованием системных вызовов.
Однако из-за буферов операционной системы это может не означать, что данные записываются на диск . Это может означать, что данные копируются из буферов, поддерживаемых вашей средой выполнения, в буферы, поддерживаемые операционной системой.
Если вы что-то пишете, и это попадает в буфер (только), и питание отключается на вашем компьютере, эти данные не находятся на диске, когда машина выключается.
Итак, для того , чтобы помочь с этим у вас есть flush
и fsync
методы, на соответствующих объектах.
Первое, flush
просто записывает любые данные, которые остаются в программном буфере, в фактический файл. Обычно это означает, что данные будут скопированы из буфера программы в буфер операционной системы.
В частности, это означает, что если другой процесс имеет тот же файл, открытый для чтения, он сможет получить доступ к данным, которые вы только что сбросили в файл. Однако это не обязательно означает, что он «постоянно» хранится на диске.
Для этого необходимо вызвать os.fsync
метод, который обеспечивает синхронизацию всех буферов операционной системы с запоминающими устройствами, для которых, другими словами, этот метод будет копировать данные из буферов операционной системы на диск.
Как правило, вам не нужно беспокоиться о любом из этих методов, но если вы находитесь в ситуации, когда паранойя о том, что на самом деле заканчивается на диске, является хорошей вещью, вы должны сделать оба вызова в соответствии с инструкциями.
Приложение в 2018 году.
Обратите внимание, что диски с механизмами кеширования стали гораздо более распространенными, чем в 2013 году, поэтому теперь задействовано еще больше уровней кэширования и буферов. Я предполагаю, что эти буферы также будут обрабатываться вызовами sync / flush, но я действительно не знаю.
with file('blah') as fd: #dostuff
конструкцию, я знаю, что она гарантирует закрытие файлового дескриптора. Это также сбрасывает или синхронизирует?fsync
необходимо для атомности. Вы не можете ожидать, что закроете файл, снова откроете его и найдете свой контент безfsync
середины. Это часто работает, но не работает в Linux с ext4 и параметрами монтирования по умолчанию, например. Такжеfsync
не гарантируется, что устройство перевернет магнит на магнитах, потому что 1: fsync может быть отключен (в режиме ноутбука), а 2: внутренняя буферизация жесткого диска может не быть указана для сброса.Потому что операционная система может этого не делать. Операция очистки принудительно помещает данные файла в кэш файлов в ОЗУ, и оттуда задача ОС - фактически отправить их на диск.
источник
actually
относительны здесь: если на целевом устройстве включено кэширование записи, данные могут не достичь фактических плат / чипов приos.fsync()
возврате.Он сбрасывает внутренний буфер, который должен заставить ОС записать буфер в файл. [1] Python использует буферизацию операционной системы по умолчанию, если вы не настроите ее, в противном случае.
Но иногда ОС все же решает не сотрудничать. Особенно с такими замечательными вещами, как задержки записи в Windows / NTFS. По сути, внутренний буфер очищен, но буфер ОС все еще удерживает его. Таким образом, вы должны указать ОС записать его на диск
os.fsync()
в этих случаях.[1] http://docs.python.org/library/stdtypes.html
источник
По сути, flush () очищает ваш буфер ОЗУ, его реальная сила в том, что он позволяет вам продолжать запись в него впоследствии - но это не следует считать лучшей / самой безопасной функцией записи в файл. Это очищает вашу оперативную память для получения большего количества данных, вот и все. Если вы хотите обеспечить безопасную запись данных в файл, используйте вместо этого close ().
источник