有没有什么方法可以不使用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

其他回答

不使用互操作,你可以使用。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

当我遇到类似的问题时,我完成了以下代码:

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

}

在Powershell中也是一样

function Test-FileOpen
{
    Param
    ([string]$FileToOpen)
    try
    {
        $openFile =([system.io.file]::Open($FileToOpen,[system.io.filemode]::Open))
        $open =$true
        $openFile.close()
    }
    catch
    {
        $open = $false
    }
    $open
}

您可以在感兴趣的文件区域上通过互操作调用LockFile。这将不会抛出异常,如果它成功,你将对文件的那一部分(由你的进程持有)拥有一个锁,这个锁将一直持有,直到你调用UnlockFile或你的进程死亡。

您可以通过尝试自己先读取或锁定文件来查看文件是否被锁定。

请在这里查看我的回答以了解更多信息。