Как открыть файл из нескольких процессов? - PullRequest
0 голосов
/ 06 октября 2010

Надеюсь, больше из "Что я делаю не так?"чем "Как я?"но вы идете ...

По сути, я пытаюсь заставить программу вести себя следующим образом:

  • Первый экземпляр программы открывается наПК1, открывает файл для доступа на чтение / запись, а затем выступает в качестве основной программы, выполняя кучу работы над некоторыми другими файлами, и я не хочу, чтобы сразу к ним обращался целый ряд пользователей.

  • Второй экземпляр программы запускается, пытается открыть файл для доступа на чтение / запись, выходит из строя, переходит в режим ведомого, открывает файл для доступа на чтение и периодически читает состояние других файлов из этого файла.

В любом случае, это план.Если кто-то может предложить лучший способ обработки решений «главный / подчиненный», я открыт для предложений.

В любом случае, в качестве подготовки к реализации у меня есть два открытых экземпляра Visual Studio.,Один запускает проект с именем «GetFile», другой - проект с именем «TryGetFile».

«GetFile» имеет объект Private myStream As IO.FileStream и открывает тестовый файл с помощью следующей строки:

myStream = IO.File.Open("\\[network path]\test.txt", IO.FileMode.OpenOrCreate,
                            IO.FileAccess.ReadWrite, IO.FileShare.ReadWrite)

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

"TryGetFile"также имеет объект Private myStream As IO.FileStream, но он пытается открыть следующий код:

myStream = IO.File.Open("\\[network path]\test.txt", IO.FileMode.Open, 
                            IO.FileAccess.Read, IO.FileShare.Read)

Это не работает вообще.Я получаю IOException, в котором сообщается, что test.txt открывается другим процессом, и мне не разрешается с ним играть.

По сути, я не вижу, в чем проблема;Я не думаю, что «TryGetFile» запрашивает какой-либо доступ к файлу, который «GetFile» запрещает.Насколько я вижу, "GetFile" вообще не должен запрещать какой-либо доступ ...

Что я здесь напортачила?

РЕДАКТИРОВАТЬ: Хм ...

Хорошо, Хенк и Ричард ответили на поставленный вопрос, указав, что проблема заключается в том, что «TryGetFile» пытается сузить разрешение на совместное использование файлов на «Чтение», где «GetFile» уже разрешает доступ к ReadWrite.Изменение «TryGetFile», чтобы также разрешить совместное использование ReadWrite, позволяет запускать код.

К сожалению, изменение кода в соответствии с их предложениями, так что и «GetFile», и «TryGetFile» разрешают совместное использование IO.FileShare.Read:

'GetFile
myStream = IO.File.Open("\\[network path]\test.txt", IO.FileMode.Open,
                            IO.FileAccess.ReadWrite, IO.FileShare.Read)

'TryGetFile
myStream = IO.File.Open("\\[network path]\test.txt", IO.FileMode.Open,
                            IO.FileAccess.Read, IO.FileShare.Read)

заставляет TryGetFile снова генерировать IOException.

Что здесь не так?

Ответы [ 3 ]

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

Вы должны быть в состоянии сделать это таким образом, во всех случаях:

  1. Открыть с помощью FileAccess.ReadWrite и FileShare.Read
  2. Если # 1 не удалось открыть с помощью FileAccess.Read и FileShare.ReadWrite

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


Обновлен с этой последней заметкой после тестирования в PowerShell ($name включает абсолютный путь к файлу, чтобы избежать эффектаPowerShell, который непосредственно не выходит за текущий текущий каталог процесса):

Первый процесс:

$file = [io.file]::Open($name, [io.filemode]::Open, [io.fileaccess]::ReadWrite, [io.fileshare]::Read)

Второй процесс:

$file = [io.file]::Open($name, [io.filemode]::Open, [io.fileaccess]::Read, [io.fileshare]::readwrite)

И я вижу в Process Explorer, чтофайл открыт в обоих процессах.

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

В вашем текущем коде TryGetFile пытается запретить другим пользователям доступ на запись. Так что сделайте последнюю строку кода;

  myStream = File.Open("\\[network path]\test.txt", FileMode.Open, 
                        FileAccess.Read, FileShare.ReadWrite)

Чтобы уточнить немного:

  • FileAccess.Read утверждает, что TryGetFile хочет только читать

  • FileShare.ReadWrite заявляет, что не имеет значения, что другие (GetFile) читают или пишут

0 голосов
/ 06 октября 2010

Значение FileShare, определяющее тип доступа к файлу других потоков.

Таким образом, вам необходимо ReadWrite как для TryGetFile, так и для GetFile.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...