正如 Jared 所说,除非打开文件的其他实体允许共享读取,否则您无法执行此操作。Excel 允许共享读取,即使对于它已打开以供写入的文件也是如此。因此,您必须使用FileShare.ReadWrite参数打开文件流。
FileShare 参数经常被误解。它指示文件的其他打开器可以做什么。它适用于过去和未来的开场白。不将 FileShare 视为对先前打开程序(例如 Excel)的追溯禁止,而是当前打开或任何未来打开不得违反的约束。
在当前尝试打开文件的情况下,FileShare.Read 表示“只有在任何先前的打开者仅为读取而打开此文件时,才能成功为我打开此文件。” 如果您在 Excel 为写入而打开的文件上指定 FileShare.Read,则您的打开将失败,因为它违反了约束,因为 Excel 将其打开为写入。
由于 Excel 已打开文件以进行写入,因此如果您希望打开成功,则必须使用FileShare.ReadWrite打开文件。考虑 FileShare 参数的另一种方式:它指定“其他人的文件访问权限”。
现在假设一个不同的场景,您正在打开一个当前未被任何其他应用程序打开的文件。FileShare.Read 说“未来的开启者只能通过读取权限打开文件”。
从逻辑上讲,这些语义是有意义的 - FileShare.Read 意味着,如果其他人已经在编写文件,您不想读取文件,如果您已经在读取文件,您也不希望其他人写入文件。FileShare.ReadWrite 意味着,即使其他人正在编写文件,您也愿意读取文件,并且在您读取文件时让其他打开者写入文件也没有问题。
在任何情况下,这都不允许多个作者。FileShare 类似于数据库 IsolationLevel。您在此处所需的设置取决于您需要的“一致性”保证。
例子:
using (Stream s = new FileStream(fullFilePath,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite))
{
...
}
或者,
using (Stream s = System.IO.File.Open(fullFilePath,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite))
{
}
附录:
System.IO.FileShare上的文档有点少。如果您想获得直接的事实,请转到Win32 CreateFile 函数的文档,它更好地解释了 FileShare 概念。