【发布时间】:2009-06-26 09:34:01
【问题描述】:
我有一个加载 excel 文件进行分析的 winforms 应用程序。目前,为了打开 excel 文件,该文件不能已经在 excel 中打开,否则当我尝试加载文件时会抛出 FileIOException。
我想做的是让我的应用程序读取文件,即使它在 excel 中打开,而不是强制用户先关闭工作表。请注意,有问题的应用程序只需要读取文件,而不是写入文件。
这可能吗?
【问题讨论】:
我有一个加载 excel 文件进行分析的 winforms 应用程序。目前,为了打开 excel 文件,该文件不能已经在 excel 中打开,否则当我尝试加载文件时会抛出 FileIOException。
我想做的是让我的应用程序读取文件,即使它在 excel 中打开,而不是强制用户先关闭工作表。请注意,有问题的应用程序只需要读取文件,而不是写入文件。
这可能吗?
【问题讨论】:
您可以尝试在打开文件时传递 FileShare.ReadWrite:
using (var stream = new FileStream(
@"d:\myfile.xls",
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite))
{
}
【讨论】:
您是如何尝试打开文件的?
如果您尝试打开它以进行读/写,那么您会遇到异常。如果您尝试以只读方式打开它,那么您应该没问题。
var file = File.Open("file.xls", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
只有当 Excel 打开文件并设置FileShare.Read 以允许其他应用程序(即您的应用程序)访问该文件时,这才有效。如果未设置,则 Excel 将以独占访问权限打开文件。注意:我认为情况并非如此,因为如果其他人打开了 Excel 文件(在 Excel 中)进行编辑,您可以打开它进行读取。
更新 - 好的,直到 darin 的 cmets 之后我才正确测试这个。您需要 FileShare.ReadWrite 标志,尽管帮助表明它是用于后续文件打开器的。甚至FileShare.Read 都不够好,我觉得更奇怪。
【讨论】:
SpreadsheetGear for .NET 可以在 Excel 打开工作簿时读取它们。这是我们用来执行此操作的代码(请注意,我们在打开文件后锁定整个文件,以防止 Excel 或任何其他应用程序在读取过程中写入):
stream = new System.IO.FileStream(path,
System.IO.FileMode.Open,
System.IO.FileAccess.Read,
System.IO.FileShare.ReadWrite,
SG.CompoundDocumentIO.Storage.OpenBufferLength);
try
{
stream.Lock(0, stream.Length);
}
catch
{
// .NET 1.1 requires cast to IDisposable
((IDisposable)stream).Dispose();
throw;
}
免责声明:我拥有 SpreadsheetGear LLC
【讨论】:
尝试复制已打开的文件,阅读并丢弃它。为了检查文件是否已经打开,请尝试读取并通过执行复制、读取、丢弃来处理异常。
【讨论】: