我有以下代码来检测文件是否已被使用:
public static bool FileInUse(string sFile)
{
FileStream file = null;
try
{
file = new FileStream(sFile, FileMode.Open, FileAccess.ReadWrite);
file.Close();
file = File.OpenWrite(sFile);
file.Close();
return false;
}
catch (Exception)
{
try { file.Close(); }
catch (Exception) { }
return true;
}
}
当文件正在使用时,new FileStream(sFile, FileMode.Open, FileAccess.ReadWrite)
不会抛出错误,但File.OpenWrite(sFile)
会抛出错误:
该进程无法访问该文件,因为该文件正被另一个文件使用 过程
为什么?因为我想检查是否可以在写入模式下打开文件。
答案 0 :(得分:3)
您用于FileStream
的构造函数默认为共享模式FileShare.Read
,这意味着将允许稍后打开文件以进行读取(但不是写入)的请求。即使文件已经打开以供阅读(如果不是独占读取),这也会起作用。
在File.OpenWrite
上,MSDN在线声明:
此方法等效于FileStream(String,FileMode,FileAccess,FileShare)构造函数重载,文件模式设置为OpenOrCreate,访问权限设置为Write,共享模式设置为None。
http://msdn.microsoft.com/en-us/library/system.io.file.openwrite(v=vs.110).aspx
这意味着File.OpenWrite
尝试获得对文件的独占读访问权,而不仅仅是独占的写访问权。
听起来,当您测试文件中的“正在使用”时,正在阅读。
两种方法都会检查该文件是否可用于独占写入。您需要确定您的应用程序是否还需要独占阅读。
答案 1 :(得分:3)
因为
File.OpenWrite(sFile) -> return new FileStream(path, FileMode.OpenOrCreate,
FileAccess.Write, FileShare.None);
但是
public FileStream(String path,FileMode mode,FileAccess access) :this(path,mode,access,FileShare.Read,DefaultBufferSize,FileOptions.None,Path.GetFileName(path),false){ }
如您所见,第一个使用FileShare.None,但第二个使用FileShare.Read
来自MSDN:
FileShare.None拒绝分享当前文件。在文件关闭之前,任何打开文件的请求(通过此过程或其他过程)都将失败。
FileShare.Read允许随后打开文件进行阅读。如果未指定此标志,则在文件关闭之前,任何打开文件以供读取(通过此进程或其他进程)的请求都将失败。但是,即使指定了此标志,仍可能需要其他权限才能访问该文件。
有点偏离主题,但是:没有很好的方法来检查文件是否正在使用或者没有,因为在您调用FileInUse方法和调用打开文件之间的时间段内,此文件可能再次被锁定。这种FileInUse方法最终是多余的。您可以在尝试独占访问文件时捕获异常。