Windows Win32 C ++ вопрос о сбросе активности файла на диск.
У меня есть внешнее приложение (запущено с использованием CreateProcess), которое создает файлы. то есть, когда он вернется, он создаст файл с некоторым содержанием.
Как я могу убедиться, что созданный процесс действительно был записан на диск, прежде чем я продолжу?
Под этим я подразумеваю не буферы C ++, а действительно очищающий диск (например, FlushFileBuffers).
Помните, что у меня нет доступа к любому файлу HANDLE - все это, конечно, скрыто во внешнем процессе.
Полагаю, я мог бы открыть свой дескриптор для файла и затем использовать FlushFileBuffers, но не ясно, как это будет работать (поскольку мой дескриптор на самом деле не содержит ничего, что требует очистки).
Наконец, я хочу, чтобы это выполнялось в пользовательском пространстве без прав администратора, поэтому я не могу использовать FlushFileBuffers для всего тома.
Есть идеи?
ОБНОВЛЕНИЕ: Почему я думаю, что это проблема?
Я работаю над приложением резервного копирования данных. По сути, он должен создать несколько файлов, как описано. Затем он должен обновить свою внутреннюю БД (используя встроенную БД SQLite).
У меня недавно была проблема с повреждением данных, возникшая во время синего экрана (причина которого не была связана с моим приложением).
Меня беспокоит целостность приложения во время сбоя системы. И да, меня это волнует, потому что это приложение для резервного копирования данных.
Случай использования, который меня беспокоит, таков:
- Небольшой файл данных создается с использованием внешнего процесса. Эта запись ожидает записи в кэш ОС на диск.
- Я обновляю БД и фиксирую. Это дисковая активность. Эта запись также ожидает в кеше ОС.
- Произошел сбой системы.
Как я понимаю, сейчас мы находимся в состоянии потенциальной гонки. Если «1» сбрасывается, а «2» - нет, то все в порядке (поскольку транзакция с БД не была зафиксирована). Если ни один из них не сбрасывается, или оба сбрасываются, мы тоже в порядке.
Насколько я понимаю, записи будут недетерминированными. то есть я не знаю, что операционная система будет гарантировать запись «1» перед «2». (Я не прав?)
Итак, если «2» сбрасывается, а «1» - нет, тогда у нас проблема.
То, что я заметил, было то, что БД была правильно обновлена, но в файле был мусор: последние две трети данных были двоичными "нулями". Теперь, я не знаю, как это выглядит, когда у вас есть часть файла, очищенная во время синего экрана, но я не удивлюсь, если бы это выглядело так.
Могу ли я гарантировать, что это причина? Нет, я не могу этого гарантировать. Я просто размышляю. Возможно, файл «естественно» поврежден из-за сбоя диска или из-за синего экрана.
Что касается производительности, я думаю, что с этим можно справиться.
Например, стандартное поведение SQLite - полная очистка файла (с использованием FlushFileBuffers) каждый раз, когда вы совершаете транзакцию. Они совершенно ясно, что если вы этого не сделаете, то во время сбоя системы у вас может быть поврежденная БД.
Кроме того, я считаю, что могу снизить производительность, только сбрасывая на «контрольные точки». Например, запись 50 файлов, очистка лота, а затем запись в БД.
Насколько вероятно, что все это будет проблемой? Бьет меня Но тогда мое приложение вполне может архивировать в момент сбоя системы или около него, так что, скорее всего, вы думаете.
Надеюсь, это объясняет, почему я не хочу этого делать.