Чтение файла, не мешая другим процессам читать его одновременно - PullRequest
1 голос
/ 30 июня 2011

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

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

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

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

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

Любые предложения или идеи?

Большое спасибо!

Ответы [ 5 ]

3 голосов
/ 30 июня 2011

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

using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
{
  // do your stuff
}

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

2 голосов
/ 30 июня 2011

ПОЦЕЛУЙ: Можете ли вы создать файл в месте, которое первая программа не просматривает, но ваше программное обеспечение - и когда вы закончите его обработку, вы затем перемещаете его в текущее место, где находится первая программа 1002 * смотрит?

В противном случае: У вас будет спор, потому что это будет гонка, чтобы увидеть, какой процесс на самом деле «замечает» файл первым и начинает работать.

Я предполагаю, что вы также не имеете никакого контроля над процессом создания файла?

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

Существует также потенциальное состояние гонки: «заметить» файл и выполнить действие (независимо от того, что это) - постоянно приостанавливать другой процесс до тех пор, пока вы не захотите запустить его (или убить и запустить его), - это единственное полностью детерминированный способ достижения того, что вы хотите в рамках ограничений.

2 голосов
/ 30 июня 2011

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

Это можно сделать из командной строки с помощью

fsutil hardlink create <NewFileName> <ExistingFileName>

Или вы можете P / Invoke функция CreateHardLink в Windows API.

0 голосов
/ 30 июня 2011

@ Ответ Прашанта вдохновил меня на это, и это очень похоже, но я верю, что это решит вашу проблему.

Если другой процесс должен соответствовать определенному шаблону имени файла

  • Переименуйте файл во что-то, что не соответствует первому, очень дешевая / быстрая операция
  • Переименуйте его, когда закончите

Если он соответствует каждому файлу в данной папке

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

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

Конечно, все еще существует возможность состояния гонки, но это должно быть намного безопаснее, чем то, что вы делаете.

0 голосов
/ 30 июня 2011

Можете ли вы создать еще один пустой файл нулевых байтов с именем .reading, который имеет то же имя, но с расширением «read». Затем, как только первый процесс завершит чтение файла, переименуйте .reading в .done, и второй процесс сможет проверить файлы .done и удалить исходный файл, поскольку и .done, и исходный файл имеют одинаковые имена, но разные расширения?

...