jia_ziwei Ответов: 1

Файл монитора с readdirectorychangesw


Недавно я выполнял задачу по мониторингу файлов в win32 c++.

Существует программное обеспечение, которое вызывает некоторый WriteFile() и FlushFileBuffer() каждые 12 secondes.So,есть пять изменений в файле за одну минуту.

Программа вызывает функцию WriteFile() для записи инкрементной временной метки в некоторую позицию файла,затем вызывает функцию WriteFile() в другую позицию файла и,наконец, вызывает функцию FlushFileBuffer.
Следующая запись-это шоу с "process monitor",которое может объяснить, что делает программное обеспечение:

14:20:11.299 Смещение Файла Записи:1153 Длина:63724
14:20:11.304 Смещение Файла Записи:64877 Длина:63724
14:20:23.304 FlushFileBuffer
14:20:23.327 Смещение Файла Записи:1153 Длина:63724
14:20:23.306 Смещение Файла Записи:64877 Длина:63724
14:20:23.204 FlushFileBuffer
14:20:35.348 Смещение Файла Записи:1153 Длина:63724
14:20:35.325 Смещение Файла Записи:64877 Длина:63724
14:20:35.268 FlushFileBuffer

Моя работа-следить за изменениями файла,когда меняется его контекст,я читаю файл и получаю метку времени из какой-то позиции файла.

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


Но после того, как я захватил изменение файла,я начинаю читать файл, потому что временная метка, о которой говорилось выше, является инкрементной, нормальная ситуация должна быть :

...
файл изменяется в N-й момент, считайте файл, значение метки времени равно time_n
файл изменяется в точке (N+1)th,считывается файл, значение метки времени равно time_n+1
...

но иногда ситуация такова

...
изменения файла в N-М,чтение файла, считывание значения метки времени-time_n
файл изменяется в точке (N+1)th,считывание файла, считывание значения метки времени-time_n
...

или
...
изменения файла в N-М,чтение файла, считывание значения метки времени-time_n+1
файл изменяется в точке (N+1)th,считывание файла, считывание значения метки времени-time_n+1
...


Я сомневаюсь, что ReadDirectoryChangesW может только сказать нам, что файл изменился и какая-то другая информация.Но это не гарантирует, что когда я получаю ответ на изменение файла, содержимое файла полностью сбрасывается на диск с помощью FlushFileBuffer.

У вас есть какие-нибудь комментарии по этому вопросу?

Что я уже пробовал:

Я попробовал "CDirectoryChangeWatcher",и там тоже такая ситуация.

1 Ответов

Рейтинг:
0

Rick York

"это не гарантирует, что, когда я получаю ответ на изменение файла, содержимое файла полностью сбрасывается на диск с помощью FlushFileBuffer."

Да, это правда. Вы, вероятно, получите уведомление при первой же записи. Есть несколько способов справиться с ситуацией. Один из них-всегда спать некоторое время (например, 500 мс или секунду), когда вы получаете уведомление, а затем считываете отметку времени. Вы также можете отслеживать последнюю прочитанную вами книгу и продолжать чтение (после уведомления) с небольшой задержкой между ними, пока не увидите, что она отличается от предыдущей.

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


jia_ziwei

Большое вам спасибо за ваш профессиональный ответ.

"Один из них заключается в том,чтобы всегда спать некоторое время (например, 500 мс или секунду), когда вы получаете уведомление, а затем прочитать отметку времени"

Я испробовал ваш метод, о котором вы сказали выше, и он может быть мне полезен.Но очень жаль,что мое руководство хочет контролировать файлы в режиме реального времени, поэтому я не могу вызвать sleep().

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

Каждый раз, когда процесс, который записывает в файл, изменяет файл, изменяется не только отметка времени из какой-то позиции файла, но и какое-то другое тело из другой позиции файла. Таким образом,я не могу "читать и продолжать читать",потому что я не могу судить о файле на диске полностью по изменению содержимого.

Я не могу контролировать процесс записи в файл.
И я проверил как синхронный, так и асинхронный, оба способа приводят к одному и тому же результату.
До этого мои коллеги реализовали эту функцию в python, а также в программе python
эта функциональность может быть реализована правильно.
Поскольку python правильно реализует эту функциональность, мое руководство считает, что c++ будет делать то же самое.
Знаете ли вы, почему python может делать это правильно?
И есть ли у вас окончательное решение?

Rick York

Я не знаю точно, что позволяет вашей программе python делать это правильно, но я могу сделать несколько предположений. Во-первых, он открывает файл немного иначе, чем вы. Возможно, это что-то изменит. Другое дело, что я считаю, что python интерпретируется, что делает его несколько медленнее, чем скомпилированный код C++. Это может привести к встроенным задержкам, которые хорошо работают с процессом написания. Но это только догадки - я не знаю истинного ответа на этот вопрос.

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

jia_ziwei

большое вам спасибо за ваш ответ.
Вы уверены, что данные не будут сброшены на диск при создании уведомления ReadDirectoryChangesW ()?

Rick York

Это хороший вопрос. Нет, я в этом не уверен. Существует утилита под названием "файловый монитор" от sysinternals.com. Я рекомендую запустить его и следить за активностью вашего файла. Возможно, он сможет ответить на ваш вопрос и дать вам больше понимания того, что происходит.