【问题标题】:Exception in opening a file that is already open打开已经打开的文件时出现异常
【发布时间】:2010-10-02 16:50:30
【问题描述】:

我正在用 C# 构建一个应用程序,我必须在其中打开一个 CSV 文件才能从中读取数据。当我在 Excel 中打开该文件时尝试从 C# 打开 CSV 文件时出现异常。异常表示该进程无法访问该文件,因为它已经打开。即使在其他应用程序中打开文件,如何解决此问题并打开文件?

谢谢, 拉克什。

【问题讨论】:

  • 请发布一些代码,向我们展示您到目前为止所做的事情
  • 这是代码:使用 (FileStream fs = new FileStream(csvOpenFileDialog.FileName, FileMode.Open, FileAccess.Read))
  • 您缺少一个论点。阅读我的答案。
  • 检查汉斯在下面提供的答案。如果文件已打开,则 FileShare.Read 似乎不起作用。 FileShare.ReadWrite 确实有效。

标签: c#


【解决方案1】:

前段时间我遇到过这个问题。

您缺少FileShare 参数。如果不指定,如果您打开一个文件,它将被您的应用程序独占锁定。但由于它已被 Excel(或任何其他应用程序)打开,您将收到异常。

你可以试试这个——我认为这将是你最好的选择——

using (FileStream fs = File.Open(<file-path>, FileMode.Open, FileAccess.Read, FileShare.Read))

这段代码说:你好 Excel!如果您允许(读取,而不是抛出异常),我想读取该文件,但我不会尝试拥有它,而且我知道您可以随时修改它。

如果这引发错误,则 Excel 甚至拒绝了您的读取访问权限。那太可惜了! 一切顺利。

【讨论】:

  • 我发现 FileShare.Read 不起作用,而 FileShare.ReadWrite 起作用
  • 如 Hans 所述,使用 FileShare.ReadWrite 而不是 FileShare.Read。
  • 我遇到了这个问题,FileShare.ReadWrite 一段时间后修复了我的问题,只是注意到我有另一个 using 块,我调用了我得到异常的方法...所以检查你的代码,如果你有这个问题......肯定是在使用文件......
  • 谢谢! FileShare.ReadWrite 解决了我的问题!
【解决方案2】:

这是可能的,但您必须仔细控制您指定的文件共享。大多数 .NET 类默认为 FileShare.Read,拒绝另一个进程写入文件。但是,如果文件是由 Excel 打开的,那将无法正常工作,因为它已经获得了对它的写入权限。您不能否认已经获得的权利。

要解决此问题,请使您的代码类似于以下内容:

        using (var fs = new FileStream(@"c:\\temp\\test.csv", FileMode.Open, 
                   FileAccess.Read, FileShare.ReadWrite))
        using (var sr = new StreamReader(fs)) {
            // Read it...
        }

注意 FileShare.ReadWrite 的使用。我验证了此代码在 Excel 打开 test.csv 时有效。

当心您可能会因此引发的潜在麻烦,当 Excel 在您读取文件时写入文件时,可能会发生奇怪的事情。您可能会读取垃圾数据、旧数据的一部分、新数据的一部分,而没有很好的诊断方法。

【讨论】:

    【解决方案3】:

    由于并发问题,您无法选择写入同一文件的两个实例。应该可以以只读方式打开一个,这样就不会出现并发问题,因为读取保证是线程安全的。 This article 应该解释如何做我建议的事情

    【讨论】:

    • 我正在以只读模式从 C# 打开文件。但我仍然得到这个例外。可能是什么问题,我该如何解决?
    【解决方案4】:

    这是不可能的。

    可以使用不同类型的保护打开文件。 Excel 以独占方式打开文件,目的是防止文件被其他程序更改,然后在 Excel 保存文件时恢复。

    Excel 可以打开文件并允许读取,但您最终可能会陷入死锁情况,即两个应用程序都打开文件以供读取,但都无法保存任何内容。

    【讨论】:

    • 根据我提供的链接,情况似乎并非如此。
    • @Woot4Moo:那篇文章是关于打开电子表格,而不是 CSV 文件,以及打开文件以进行只读访问,而不是打开已经以独占方式打开的文件,所以我很抱歉但它根本不相关。
    • 其实很相关。如果 OP 查看文件的打开顺序,您可以让 Excel 首先将文件作为只读实例打开,这可能会缓解问题
    • @Woot4Moo:是的,这是可能的,但这篇文章是关于 API,而不是 Excel 应用程序。
    • @Woot4Moo:不,它没有。您链接到正确的文章了吗?
    【解决方案5】:

    this answer 建议的另一种解决方案是将文件复制到临时文件并打开它。

    使用

    System.IO.File.Copy(sourcepath, copypath, false);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-07-16
      • 2014-05-02
      • 2018-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多