File.ReadAllLines() 无法读取由 Excel 打开的文件
File.ReadAllLines() fails to read from a file that is opened by Excel
假设我在 Excel 中打开一个文件,我知道我不能向它写入任何内容,因为它将 "locked" 由 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 中以只读方式打开文件吗?那行得通吗?
很可能是其他程序锁定了文件,不允许其他程序执行此操作。如果是这种情况,您无能为力:/
查看此 SO,其中有更详细的解释:How do I open an already opened file with a .net StreamReader?
如果您是第一个打开它的程序,您可以以允许其他人打开的方式打开它:)
首先,您需要了解以下几点:
- 只要 process/thread 打开文件,process/thread 就可以只读、只写或同时访问文件。查看
FileAccess
Enum 了解更多信息。
- 此外,process/thread 可以指定是否共享对文件的访问权限(例如,共享只读、只写、两者都共享,或者根本没有共享访问权限)。查看
FileShare
Enum 了解更多。
- 如果其他进程根本不共享对该文件的访问权限,那么您将无法访问该文件,无论它是用于读取还是写入。
现在 AFAIK,Excel 确实共享文件访问权限 用于读取 ,(但不共享用于写入)。因此,为了能够在 Excel 打开文件时访问该文件,您需要执行以下操作:
- 只打开文件进行读取(因为您无权写入)。
- 允许读取和写入文件因为另一个进程(即Excel)需要同时具有.
问题是,虽然 File.ReadAllLines()
以只读方式打开文件,但它 不 共享对文件用于写入(仅用于读取)。为了进一步说明,File.ReadAllLines()
默认使用具有以下值的 StreamReader
internally 1, which --also internally-- uses a 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
枚举设置适当的值。因此,您的代码应如下所示:
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
希望对您有所帮助。
参考文献:
假设我在 Excel 中打开一个文件,我知道我不能向它写入任何内容,因为它将 "locked" 由 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 中以只读方式打开文件吗?那行得通吗?
很可能是其他程序锁定了文件,不允许其他程序执行此操作。如果是这种情况,您无能为力:/
查看此 SO,其中有更详细的解释:How do I open an already opened file with a .net StreamReader?
如果您是第一个打开它的程序,您可以以允许其他人打开的方式打开它:)
首先,您需要了解以下几点:
- 只要 process/thread 打开文件,process/thread 就可以只读、只写或同时访问文件。查看
FileAccess
Enum 了解更多信息。 - 此外,process/thread 可以指定是否共享对文件的访问权限(例如,共享只读、只写、两者都共享,或者根本没有共享访问权限)。查看
FileShare
Enum 了解更多。 - 如果其他进程根本不共享对该文件的访问权限,那么您将无法访问该文件,无论它是用于读取还是写入。
现在 AFAIK,Excel 确实共享文件访问权限 用于读取 ,(但不共享用于写入)。因此,为了能够在 Excel 打开文件时访问该文件,您需要执行以下操作:
- 只打开文件进行读取(因为您无权写入)。
- 允许读取和写入文件因为另一个进程(即Excel)需要同时具有.
问题是,虽然 File.ReadAllLines()
以只读方式打开文件,但它 不 共享对文件用于写入(仅用于读取)。为了进一步说明,File.ReadAllLines()
默认使用具有以下值的 StreamReader
internally 1, which --also internally-- uses a 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
枚举设置适当的值。因此,您的代码应如下所示:
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
希望对您有所帮助。
参考文献: