Какой наименее инвазивный способ чтения заблокированного файла в C # (возможно, в небезопасном режиме)? - PullRequest
37 голосов
/ 25 августа 2010

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

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

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

Ответы [ 3 ]

47 голосов
/ 25 августа 2010

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

Хитрость заключается в использовании FileShare.ReadWrite (из статьи):

private void LoadFile()
{
    try
    {
        using(FileStream fileStream = new FileStream(
            "logs/myapp.log",
            FileMode.Open,
            FileAccess.Read,
            FileShare.ReadWrite))
        {
            using(StreamReader streamReader = new StreamReader(fileStream))
            {
                this.textBoxLogs.Text = streamReader.ReadToEnd();
            }
        }
    }
    catch(Exception ex)
    {
        MessageBox.Show("Error loading log file: " + ex.Message);
    }
} 
15 голосов
/ 10 сентября 2014

Принятый ответ неверен.Если файл действительно заблокирован, вы не можете просто изменить общий доступ к файлам.Это будет работать, если блокировка была установлена ​​с этой опцией файлового обмена, но это не означает, что это так.Фактически, вы можете довольно легко протестировать решение @CaffGeek, открыв файл без FileShare.ReadWrite и затем попытавшись открыть его с этим флагом в ReadWrite.Вы получите, что файл используется другим процессом.

Код:

        string content;
        var filePath = "e:\\test.txt";

        //Lock Exclusively the file
        var r = File.Open(filePath, FileMode.Open, FileAccess.Write, FileShare.Write);

        //CaffGeek solution
        using (FileStream fileStream = new FileStream(
        filePath,
        FileMode.Open,
        FileAccess.Read,
        FileShare.ReadWrite))
        {
            using (StreamReader streamReader = new StreamReader(fileStream))
            {
                content = streamReader.ReadToEnd();
            }
        }

Как видите, он вылетает.Этот результат одинаков с любым методом FileStream, таким как File.Open.Это приведет к сбою того, что вы положили для FileShare во время открытой стадии.

        //OPEN FOR WRITE with exclusive
        var r = File.Open(filePath, FileMode.Open, FileAccess.Write, FileShare.Write);


        //OPEN FOR READ with file share that allow read and write
        var x = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); //Crash

Копирование файла также не вариант.Вы можете попробовать самостоятельно, открыв файл исключительно и попытаться скопировать файл в проводнике Windows или по коду:

        var filePath = "e:\\test.txt";
        var filePathCopy = "e:\\test.txt.bck";

        //Lock the file
        var r = File.Open(filePath, FileMode.Open, FileAccess.Write, FileShare.Write);

        File.Copy(filePath, filePathCopy);
        var x = File.Open(filePathCopy, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
        using (var reader = new StreamReader(x))
        {
            content = reader.ReadToEnd();
        }

        r.Close();
        File.Delete(filePathCopy);

Этот код вылетает при нажатии строки File.Copy.Исключение такое же, как и раньше: файл используется другим процессом.

Вам нужно убить процесс, который заблокировал файл, если вы хотите прочитать его, ИЛИ, если у вас есть исходный кодфайл, который блокирует файл, чтобы изменить его на использование FileShare.ReadWrite вместо FileShare.Write.

1 голос
/ 25 августа 2010

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

Или, возможно, StreamReader для FileStream в зависимости от того, как SQL открыл файл?

new FileStream("c:\myfile.ext", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...