открыть файл в эксклюзивном режиме в C # - PullRequest
17 голосов
/ 26 марта 2009

Я хочу открыть файл для чтения в монопольном режиме, и если файл уже открыт каким-либо процессом / потоком, я хочу получить исключение. Я попытался следующий код, но не работает, даже если я открыл foo.txt, я все еще могу получить оператор Console.WriteLine. Есть идеи?

static void Main(string[] args)
{
    using (Stream iStream = File.Open("c:\\software\\code.txt", FileMode.Open,
    FileAccess.Read, FileShare.None))
    {
        Console.WriteLine ("I am here");
    }

    return;
}

Ответы [ 5 ]

19 голосов
/ 26 марта 2009

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

static void Main(string[] args)
{
    // Make sure test.txt exists before running. Run this app twice to see.
    File.Open("test.txt", FileMode.Open, FileAccess.Read, FileShare.None);
    Console.ReadKey();
}
3 голосов
/ 26 марта 2009

Проверьте это, написав простую консольную программу, которая открывает файл и ждет:

static void Main(string args[])
{
    using (FileStream f = File.Open("c:\\software\\code.txt", FileMode.Open, FileAccess.Read, FileShare.None))
    {
        Console.Write("File is open. Press Enter when done.");
        Console.ReadLine();
    }
}

Запустите эту программу из командной строки (или другого экземпляра Visual Studio), а затем запустите вашу программу. Таким образом, вы можете поиграть с разными значениями FileMode и FileShare, чтобы убедиться, что ваша программа корректно реагирует во всех случаях.

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

3 голосов
/ 26 марта 2009

То, что вы сделали, правильно.

Если вам нужны все открытые файлы, NtQuerySystemInformation может найти способ

Вы можете получить идею от http://www.codeproject.com/KB/shell/OpenedFileFinder.aspx

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

2 голосов
/ 26 марта 2009

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

Такие программы, как Блокнот и Visual Studio, не блокируют текстовые файлы.

2 голосов
/ 26 марта 2009

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

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

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