【问题标题】:Cannot open filestream for reading but still I am able to copy the file?无法打开文件流进行读取,但我仍然可以复制文件?
【发布时间】:2017-09-07 12:55:12
【问题描述】:

这一行:

using (FileStream fs = File.Open(src, FileMode.Open, FileAccess.Read, FileShare.Read))

抛出:

System.IO.IOException:进程无法访问文件“X”,因为 它正被另一个进程使用。

当我将这一行替换为:

File.Copy(src, dst, true);
using (FileStream fs = File.Open(dst, FileMode.Open, FileAccess.Read, FileShare.Read))

它有效。

但是为什么我可以复制,它肯定会读取文件的全部内容,而不能直接读取文件?有解决办法吗?

【问题讨论】:

  • 如果你使用FileShare.ReadWrite会怎样?如果另一个进程具有写访问权限,如果您只允许共享读访问权限,您的请求将失败。
  • @SamiKuhmonen 是的!但为什么?哦,我明白了...
  • 如果此问题没有重复项,请不要删除它。这是一个有效的问题。

标签: c# .net windows file-io filestream


【解决方案1】:

当您打开文件时,系统会检查访问模式和共享模式。任何进程的访问方式都必须兼容其他进程的共享方式。因此,如果 A 想要阅读,其他人必须允许在共享模式下阅读。写作也一样。

如果进程 A 已打开一个文件进行写入,而您说 SharingMode.Read,则调用将失败。在这种情况下,您是在说“其他人只能从文件中读取,而不能写入。”

如果您指定ShareMode.ReadWrite,您是在说“其他人可以读或写,我不在乎”,如果没有其他进程指定ShareMode.Write,您可以从文件中读取。

【讨论】:

    【解决方案2】:

    但为什么我可以复制,它肯定会读取文件的全部内容

    嗯,从概念上讲,它会读取整个文件,尽管它可能发生在比复制流更低的级别。在 Windows 上,它是对 CopyFileEx 系统函数的调用,传入路径。在 *nix 系统上,它也使用系统调用,但会使用 FileAccess.Read, FileShare.Read 为该调用打开源文件,因此您会遇到同样的问题。

    同时被限制直接读取文件?

    如果文件可能被写入,那么您将无法打开它FileShare.Read,因为在您正在执行的各种操作之间的某个时刻,文件可能会被更改,并且您的操作会给出错误的结果。

    CopyFileEx 可以通过防止在其运行的短时间内发生的任何写入影响结果来成功。没有办法提供更通用的形式,因为无法知道您将再次快速关闭它的流。

    有解决办法吗?

    解决方法是什么?您无法打开流,或者您可以复制文件?对于前者,后者提供了这样一种解决方法:复制文件以获取它的快照,但请注意,它不能保证。

    【讨论】:

    • 感谢您的解释,我只是把FileShare.Read误认为FileShare.ReadWrite 所以FileShare.ReadWrite 为我解决了这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-16
    • 1970-01-01
    • 2015-01-19
    • 2021-02-07
    • 1970-01-01
    相关资源
    最近更新 更多