2009-03-26 6 views
15

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

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; 
} 
+0

«даже если я открыл foo.txt» -> как вы его открыли? –

+0

Да, Мехрдад. Я открыл его, затем выполнил мою программу, все еще мог прочитать инструкцию Console.WriteLine. Есть идеи? – George2

+0

С помощью блокнота? Блокнот не блокирует файл при запуске. Он читает файл в памяти и открывает его для записи при сохранении. –

ответ

1

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

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

+0

Спасибо, Cerebrus, вы правы, и я использую блокнот, чтобы открыть его и запустить мою программу для тестирования. Любые идеи, чтобы проверить, открыт ли файл или нет (например, я хочу, чтобы мой код мог проверить, открыл ли блокнот)? – George2

+0

Нет, я не думаю, что есть ... кроме того, чтобы поймать IOException в коде, который пытается впоследствии прочитать файл. – Cerebrus

+0

Моя ситуация: поток сериализуется (используя сериализацию XML) в файл, из этого файла считывается другой поток читателя. Я не хочу, чтобы поток читателей работал над этим файлом, в то время как сериализация XML в процессе, любые идеи? – George2

16

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

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(); 
} 
+0

Спасибо Mehrdad, в любом случае, проверить, открыт ли файл другим потоком/процессом? – George2

+0

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

+0

Спасибо Мехридаду, я проверил, что вы правы. моя ситуация, поток сериализует (используя сериализацию XML) в файл, из этого файла считывается другой поток читателя. Я не хочу, чтобы поток читателей работал над этим файлом, в то время как сериализация XML в процессе, любые идеи? – George2

2

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

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

+0

Спасибо, Якоб, в любом случае, проверить, открыт ли файл другим потоком/процессом? – George2

+0

Hi Jakob, моя ситуация, поток сериализуется (используя сериализацию XML) в файл, из этого файла считывается другой поток читателя. Я не хочу, чтобы поток читателей работал над этим файлом, в то время как сериализация XML в процессе, любые идеи? – George2

+0

Как вы сериализуете? При сериализации вы должны открыть файл исключительно (то есть FileAccess.Write и FileShare.None). –

3

Что вы сделали правильно.

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

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

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

+0

Спасибо lakshmanaraj, моя ситуация, поток сериализуется (используя сериализацию XML) в файл, из этого файла считывается другой поток читателя. Я не хочу, чтобы поток читателей работал над этим файлом, в то время как сериализация XML в процессе, любые идеи? – George2

+0

Вы можете заблокировать файл или сделать мьютекс, установив семафор в операцию. – lakshmanaraj

+0

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

2

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

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, чтобы убедиться, что ваша программа реагирует правильно во всех случаях.

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

+0

Привет, Джим, моя ситуация, один поток копирует файл (используя метод File.Move), а другой поток читается из файла. Я не хочу, чтобы читательский поток читал часть файла во время копирования (вот почему я хочу иметь эксклюзивный открытый режим), опубликовал ли мой код эту проблему? – George2

+0

Да, ваш код решает эту проблему. Он не откроет файл, если File.Move находится в середине копирования. –

+0

Джим, как узнать, открыла ли его программа (!)? Или блокнот или что-то еще. Или как узнать, копируется ли он прямо сейчас? –