File.ReadAllLines () не удается прочитать из файла, который открыт в Excel - PullRequest
0 голосов
/ 04 мая 2018

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

Но я могу это прочитать? Или это тоже невозможно?

Я использую следующий код:

If System.IO.File.Exists(file) Then
    output = System.IO.File.ReadAllLines(file).ToList
    If unique Then
        output = output.Distinct.ToList
    End If
Else
    output = New Generic.List(Of String)
End If

Как заставить это работать?

Можно ли открыть файл только для чтения в Excel? Будет ли это работать?

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Прежде всего, вам необходимо знать о следующих моментах:

  • Когда файл / процесс открывается потоком, процесс / поток может получить доступ к файлу только для чтения, только для записи или для обоих. Проверьте FileAccess Enum для получения дополнительной информации.
  • Кроме того, процесс / поток может указывать, является ли доступ к файлу общим или нет (например, общий доступ только для чтения, только для записи, для обоих или вообще отсутствует общий доступ). Проверьте FileShare Enum для более.
  • Если другой процесс вообще не разделяет доступ к файлу, вы не сможете получить доступ к файлу, будь то для чтения или записи.

Теперь AFAIK, Excel предоставляет доступ к файлу для чтения , (но не для записи). Итак, чтобы иметь возможность доступа к файлу, когда он открыт в Excel, вам нужно сделать следующее:

  • Открыть файл для чтения только (так как у вас нет доступа для записи).
  • Разрешить доступ к файлу как для чтения, так и для записи , поскольку другой процесс (т. Е. Excel) должен иметь оба .

Дело в том, что, хотя File.ReadAllLines() открывает файл только для чтения, он не разделяет доступ к файлу для записи (только для чтение). Чтобы уточнить больше, File.ReadAllLines() использует StreamReader внутренне 1 , который - также внутренне - использует FileStream со следующими значениями по умолчанию: 2

New FileStream(path, 
               FileMode.Open,
               FileAccess.Read,     ' This is good.
               FileShare.Read,      ' This is the problem (see the code below).
               ' ...

Работает, если файл не открыт другим процессом , для которого требуется доступ на запись в файл . Следовательно, вам нужно создать FileStream и установить соответствующие значения для FileAccess и FileShare Enums. Итак, ваш код должен выглядеть примерно так:

Dim output As New List(Of String)
If IO.File.Exists(file) Then
    Using fs As New IO.FileStream(file,
                                  IO.FileMode.Open,
                                  IO.FileAccess.Read,       ' Open for reading only.
                                  IO.FileShare.ReadWrite)   ' Allow access for read/write.
        Using reader As New IO.StreamReader(fs)
            While Not reader.EndOfStream
                Dim currentLine As String = reader.ReadLine()
                If unique AndAlso output.Contains(currentLine) Then Continue While
                output.Add(currentLine)
            End While
        End Using
    End Using
End If

Надеюсь, это поможет.


Ссылка:

1 InternalReadAllLines() источник.

2 Внутренний источник конструктора StreamReader.

0 голосов
/ 04 мая 2018

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

Проверьте это SO, которое объясняет более подробно: Как открыть уже открытый файл с помощью .net StreamReader?

Если бы вы были программой, которая открывала его в первую очередь, вы могли бы открыть ее так, чтобы другие могли ее открыть:)

...