有没有什么方法可以不使用try/catch块来检查文件是否被锁定?
现在,我所知道的唯一方法是打开文件并捕获任何System.IO.IOException。
有没有什么方法可以不使用try/catch块来检查文件是否被锁定?
现在,我所知道的唯一方法是打开文件并捕获任何System.IO.IOException。
当前回答
不使用互操作,你可以使用。net FileStream类方法Lock和Unlock:
文件流。锁 http://msdn.microsoft.com/en-us/library/system.io.filestream.lock.aspx
文件流。解锁 http://msdn.microsoft.com/en-us/library/system.io.filestream.unlock.aspx
其他回答
您可以通过尝试自己先读取或锁定文件来查看文件是否被锁定。
请在这里查看我的回答以了解更多信息。
我最后做的是:
internal void LoadExternalData() {
FileStream file;
if (TryOpenRead("filepath/filename", 5, out file)) {
using (file)
using (StreamReader reader = new StreamReader(file)) {
// do something
}
}
}
internal bool TryOpenRead(string path, int timeout, out FileStream file) {
bool isLocked = true;
bool condition = true;
do {
try {
file = File.OpenRead(path);
return true;
}
catch (IOException e) {
var errorCode = Marshal.GetHRForException(e) & ((1 << 16) - 1);
isLocked = errorCode == 32 || errorCode == 33;
condition = (isLocked && timeout > 0);
if (condition) {
// we only wait if the file is locked. If the exception is of any other type, there's no point on keep trying. just return false and null;
timeout--;
new System.Threading.ManualResetEvent(false).WaitOne(1000);
}
}
}
while (condition);
file = null;
return false;
}
您可以在感兴趣的文件区域上通过互操作调用LockFile。这将不会抛出异常,如果它成功,你将对文件的那一部分(由你的进程持有)拥有一个锁,这个锁将一直持有,直到你调用UnlockFile或你的进程死亡。
当我遇到类似的问题时,我完成了以下代码:
public class FileManager
{
private string _fileName;
private int _numberOfTries;
private int _timeIntervalBetweenTries;
private FileStream GetStream(FileAccess fileAccess)
{
var tries = 0;
while (true)
{
try
{
return File.Open(_fileName, FileMode.Open, fileAccess, Fileshare.None);
}
catch (IOException e)
{
if (!IsFileLocked(e))
throw;
if (++tries > _numberOfTries)
throw new MyCustomException("The file is locked too long: " + e.Message, e);
Thread.Sleep(_timeIntervalBetweenTries);
}
}
}
private static bool IsFileLocked(IOException exception)
{
int errorCode = Marshal.GetHRForException(exception) & ((1 << 16) - 1);
return errorCode == 32 || errorCode == 33;
}
// other code
}
然后,在这两行之间,另一个进程可以很容易地锁定文件,给您带来您一开始试图避免的相同问题:异常。
但是,通过这种方式,您将知道问题是暂时的,并稍后重试。(例如,您可以编写一个线程,如果在尝试写入时遇到锁,则会不断重试,直到锁消失。)
另一方面,IOException本身还不够特定,以至于锁定是导致IO失败的原因。可能有一些不是暂时的原因。