Очистить кэш записи на диск - PullRequest
4 голосов
/ 06 октября 2008

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

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

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

Ответы [ 5 ]

8 голосов
/ 19 июля 2011

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

4 голосов
/ 06 мая 2009

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

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

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

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

2 голосов
/ 06 мая 2009

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

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

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

2 голосов
/ 06 октября 2008

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

.Net

В потоках ввода-вывода есть метод .Flush, который делает то, что вы хотите.

Win32 API

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

РЕДАКТИРОВАТЬ (на основе комментария от ОА): FlushFileBuffers не нуждается в административных привилегиях; это происходит только в том случае, если переданный ему дескриптор является дескриптором тома, а не отдельного файла.

1 голос
/ 06 октября 2008

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

...