Прежде всего, вам необходимо знать о следующих моментах:
- Когда файл / процесс открывается потоком, процесс / поток может получить доступ к файлу только для чтения, только для записи или для обоих. Проверьте
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.