-1

假设我在 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 中以只读方式打开文件吗?那会奏效吗?

4

2 回答 2

1

很可能锁定文件的其他程序不允许其他程序执行此操作。如果是这种情况,您无能为力:/

查看此 SO,其中更详细地解释了:如何使用 .net StreamReader 打开已打开的文件?

如果您是首先打开它的程序,您可以以允许其他人打开的方式打开它:)

于 2018-05-04T17:44:49.873 回答
1

首先,您需要了解以下几点:

  • 每当一个文件被进程/线程打开时,进程/线程可以访问该文件以只读、只写或两者兼而有之。检查FileAccess枚举以获取更多信息。
  • 此外,进程/线程可以指定对文件的访问是否是共享的(例如,只读共享、只写共享、两者都共享或根本不共享访问)。检查FileShare枚举以获取更多信息。
  • 如果其他进程根本不共享对文件的访问权限,那么无论是用于读取还是写入,您都无法访问该文件。

现在 AFAIK,Excel 确实共享文件访问权限以进行读取,(但不共享用于写入)。因此,为了能够在 Excel 打开文件时访问该文件,您需要执行以下操作:

  • 以只读方式打开文件(因为您无权写入)。
  • 允许对文件进行读写访问,因为其他进程(即 Excel)需要同时具有.

问题是,虽然以只读方式File.ReadAllLines()打开文件,但它共享对文件的写入权限(仅用于读取)。为了澄清更多,在内部File.ReadAllLines()使用1,它——也在内部——默认使用具有以下值的 a :2StreamReaderFileStream

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

除非该文件被另一个需要对该文件进行写访问的进程打开,否则该方法有效。因此,您需要为和枚举创建FileStream并设置适当的值。因此,您的代码应如下所示:FileAccessFileShare

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 内部构造函数源。

于 2018-05-04T18:26:04.947 回答