Очистить кеш записи на диск

Если политика для диска в Windows XP и Vista настроена на включение кэширования записи на жесткий диск, есть ли способ очистить только что записанный файл и убедиться, что он был сохранен на диске?

Я хочу сделать это программно на C++.

При закрытии файла происходит сброс на уровне приложения, но не на уровне операционной системы. Если питание отключается от ПК после закрытия файла, но до того, как операционная система очистит кэш записи на диск, файл будет утерян, даже если он был закрыт.

Вы имеете в виду программно? Вопрос не проясняет

1800 INFORMATION 06.10.2008 12:16

Мы предполагаем, что ваш вопрос касается программирования, но вы не указали среду разработки.

tzot 06.10.2008 12:41
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
2
17 277
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Ответ принят как подходящий

Вы не указали среду разработки, поэтому:

.Сеть

Потоки ввода-вывода имеют метод .Flush, который делает то, что вы хотите.

Win32 API

Существует вызов FlushFileBuffers, который принимает в качестве аргумента дескриптор файла.

ИЗМЕНИТЬ (на основе комментария OA): FlushFileBuffers не требует административных привилегий; это происходит, только если переданный ему дескриптор является дескриптором тома, а не отдельного файла.

Похоже, это сработает. К сожалению, приложение должно работать без прав администратора.

selwyn 06.10.2008 15:24

Я не смог найти этот .NET-метод. Насколько я понимаю, единственное место, где фреймворк использует FlushFileBuffers, - это SerialStream. Я подозреваю, что p / вызов FlushFileBuffers - безопасная ставка.

Will Dean 26.03.2009 02:08

Я обнаружил, что вызов FlushFileBuffers через pInvoke может вызвать исключение (stackoverflow.com/q/9195807/4540). В .NET 4 проще и безопаснее просто вызвать FileStream.Flush (true), как предлагает @jimvfr (stackoverflow.com/a/3992428/4540).

Eric 08.02.2012 19:37

Из документов Microsoft вы должны использовать _flushall и ссылку в COMMODE.OBJ, чтобы гарантировать, что все буферы были зафиксированы на диске.

Нам также пришлось добавить опцию режима "c" во время fopen ()

Artie Leech 17.07.2019 18:59

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

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

Чтобы гарантировать, что ваши данные будут записаны на физический уровень, вы должны отключить кеш записи в вашей операционной системе. Чаще всего это приводит к снижению производительности на один или два порядка при работе с большим количеством небольших io-операций. Поддержка батарей (ИБП) или диски, которые принимают команды для очистки дискового кэша записи, - еще один вариант решения этой проблемы.

Windows будет принудительно очищать дисковый кеш для важных данных, если для политики диска не установлено значение «Отключить сброс буфера кэша записи Windows».

Zan Lynx 28.09.2009 18:31

Конечно будет. Однако, если кэш записи жесткого диска включен, диск может остановить операцию записи. Прочтите, например: support.microsoft.com/kb/259716/EN-US Цитата: «При включении кэширования записи может произойти повреждение файловой системы и / или потеря данных, если в машине произойдет сбой питания, устройства или системы, и она не может быть выключена должным образом».

Philipp 01.10.2009 17:52

Фактически, Windows принудительно сбросит кэширование для FlushFileBuffers () независимо от того, была ли включена буферизация кэша записи и даже если была включена очистка кеша записи (ранее известная как «флажок повышенной производительности»).

Vladislav Vaintroub 07.06.2011 09:36

Вы не должны исправлять это при закрытии файла. Windows будет кэшировать, если вы не откроете файл, передав FILE_FLAG_WRITE_THROUGH в CreateFile ().

Вы также можете пройти FILE_FLAG_NO_BUFFERING; это говорит Windows не хранить копию байтов в кеше.

Согласно документации CreateFile на MSDN, это более эффективно, чем FlushFileBuffers ().

См. Также буферизация файлов и кеширование файлов в MSDN.

.NET FileStream.Flush () НЕ будет очищать кеш Windows для содержимого этого файла; Flush () очищает только внутренний файловый буфер .NET. В .NET 4.0 Microsoft исправила проблему, добавив в Flush () необязательный параметр, который, если задано значение true, вызывает вызов FlushFileSystemBuffers. В .NET 3.5 и ниже ваш единственный выбор - вызвать FlushFileBuffers через pinvoke. См. Комментарий сообщества MSDN FileStream.Flush, чтобы узнать, как это сделать.

ВНИМАНИЕ: .Net 4.0 Flush (true) не исправляет !!!! Отчет об ошибке MS здесь говорит, что file.Flush (true) неисправен, затем исправлен, но не сообщает, в какой версии или пакете обновления он был исправлен! Похоже, ошибка заключалась в том, что если внутренний буфер .NET FileStream пуст, Flush (true) ничего не сделал ??

jimvfr 09.11.2012 06:38

Смотрите здесь: https://jeffpar.github.io/kbarchive/kb/066/Q66052/

Когда вы изначально открываете файл с помощью fopen, включите опцию режима «c» в качестве ПОСЛЕДНЕЙ ОПЦИИ:

fopen( path, "wc") // w - write mode, c - allow immediate commit to disk

Затем, когда вы хотите принудительно сбросить на диск, вызовите

_flushall()

Мы сделали этот звонок перед звонком

fclose()

У нас возникла именно та проблема, которую вы описали, и этот подход исправил ее.

Обратите внимание, что этот подход НЕ требует административных прав, которые требуются FlushFileBuffersделает, как уже упоминалось другими.

С этого сайта выше:

"Microsoft C / C++ версии 7.0 представляет параметр режима" c "для функции fopen () функция. Когда приложение открывает файл и указывает режим "c", библиотека времени выполнения записывает содержимое файлового буфера на диск, когда приложение вызывает функцию fflush () или _flushall (). "

Другие вопросы по теме