这一行:
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))
它有效。
但是为什么我可以复制,它肯定会读取文件的整个内容,同时被限制直接读取文件?有解决方法吗?
答案 0 :(得分:5)
当您打开文件时,会检查访问模式和共享模式。任何进程的访问模式必须与其他进程的共享模式兼容。因此,如果A想要读取,则其他人必须允许在共享模式下读取。写作也一样。
如果进程A打开了一个用于写入的文件,并且您说SharingMode.Read
则该呼叫将失败。在这种情况下,您说“其他人只能从文件中读取,而不是写入”。
如果您指定ShareMode.ReadWrite
,您说“其他人可以读取或写入,我不关心”,如果没有其他进程指定ShareMode.Write
,您可以从文件中读取。
答案 1 :(得分:1)
但为什么我可以复制,这肯定会读取文件的全部内容
嗯,从概念上讲它会读取整个文件,尽管它可能比复制流更低。在Windows上,它是对CopyFileEx
系统函数的调用,传入路径。在* nix系统上,它也使用系统调用,但是为该调用打开了FileAccess.Read, FileShare.Read
的源文件,因此您会遇到同样的问题。
被限制直接阅读文件?
如果某个文件可能被写入,那么您无法打开它FileShare.Read
,因为在您执行的各种操作之间的某个时刻,该文件可能会被更改,并且您的操作会产生错误的结果。
CopyFileEx
可以通过阻止在其运行的短时间内发生的任何写入影响结果来成功。没有办法提供更一般的形式,因为没有办法知道你会再次快速关闭它。
有解决方法吗?
解决方法是什么?你无法打开流,或者你可以复制文件?对于前者,后者提供了这样的解决方法:复制文件以获取它的快照,但请注意它不能保证。