Вопрос

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

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

Это было полезно?

Решение

Когда вы открываете файл для чтения в .NET, он в какой-то момент попытается создать дескриптор файла, используя СоздатьФайл Функция API, которая устанавливает код ошибки который можно использовать, чтобы понять, почему это не удалось:

const int ERROR_SHARING_VIOLATION = 32;
try
{
    using (var stream = new FileStream("test.dat", FileMode.Open, FileAccess.Read, FileShare.Read))
    {
    }
}
catch (IOException ex)
{
    if (Marshal.GetLastWin32Error() == ERROR_SHARING_VIOLATION)
    {
        Console.WriteLine("The process cannot access the file because it is being used by another process.");
    }
}

Другие советы

Есть полезная дискуссия группы Google который вам действительно стоит прочитать.Один из вариантов близок к дарину;однако, чтобы гарантировать получение правильной ошибки win32, вам действительно следует самостоятельно вызвать API-интерфейс win32 OpenFile() (в противном случае вы действительно не будете знать, какую ошибку вы получаете).

Другой способ — проанализировать сообщение об ошибке:это не удастся, если ваше приложение будет запущено на другой языковой версии.

Третий вариант — взломать класс исключений с помощью отражения, чтобы получить фактический HRESULT.

Ни одна из альтернатив на самом деле не настолько привлекательна:ИМХО иерархия IOException выиграет от еще нескольких подклассов.

Чтобы прочитать данные, вы можете сделать:

Использование (fileStream fs = new FileStream (fileName, fileMode.open, fileAccess.read, fileshare.readwrite | fileshare.delete)) {....}

и сохранить в файл:

Использование (fileStream fs = new FileStream (FileName, fileMode.append, fileAccess.write, fileshare.read | fileshare.delete)) {...}

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

Вы можете открыть его (как описано Безье), а затем попытаться заблокировать разделы (или весь файл):http://www.java2s.com/Code/VB/File-Directory/Lockandunlockafile.htm

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

Если вы выполняете чтение и запись, я предполагаю, что вы делаете это в разных потоках, и в этом случае взгляните на класс ReaderWriteLock, который сделает это за вас и позволит вам предоставлять тайм-ауты.

http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlock.aspx

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

fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read));

Вы можете сравнить тип IOException, чтобы проверить, не является ли это чем-то другим.

Такой как

if (ex is FileNotFoundException)

Возможно, вам захочется поискать справку по System.IO.Многие исключения в этом классе наследуются от Исключение IO.Помимо проверки того, является ли это исключением другого типа, вам, возможно, придется просмотреть сообщение в описании или попробовать выполнить вызов Win32 API в shell32.dll.Там может быть функция, позволяющая проверить, заблокирован ли файл.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top