当前位置:  开发笔记 > 编程语言 > 正文

如何轻松检查.NET中的文件是否被拒绝访问?

如何解决《如何轻松检查.NET中的文件是否被拒绝访问?》经验,为你挑选了2个好方法。

基本上,我想在实际尝试打开文件之前检查是否有权打开文件; 除非必须,否则我不想使用try/catch进行此检查.有没有我可以检查的文件访问属性?



1> Joel Coehoor..:

我过去曾做过无数次这样的事情,而且几乎每次我都这样做,我甚至做错了.

文件权限(甚至文件存在)是易变的 - 它们可以随时更改.感谢Murphy定律,这尤其包括检查文件和尝试打开文件之间的短暂时间.如果您位于您知道需要先检查的区域,则更有可能进行更改.但奇怪的是,它永远不会发生在您的测试或开发环境中,而这些环境往往是相当静态的.这使得问题很难在以后跟踪,并使这种错误很容易使其投入生产.

What this means is that you still have to be able to handle the exception if file permissions or existence are bad, in spite of your check. Exception handling code is required, whether or not you check for the permissions of the file in advance. Exception handling code provides all of the functionality of existence or permissions checks. Additionally, while exception handlers like this are known to be slow, it's important to remember that disk i/o is even slower... a lot slower... and calling the .Exists() function or checking permissions will force an additional trip out the file system.

总之,在尝试打开文件之前进行初始检查既冗余又浪费.与异常处理相比没有额外的好处,它实际上会伤害您的性能,而不是帮助,它会增加必须维护的代码的成本,并且可能会在您的代码中引入细微的错误.初步检查没有任何好处.相反,这里正确的做法是尝试打开文件,如果失败则将您的努力投入到良好的异常处理程序中.即使您只是检查文件是否存在,情况也是如此.这种推理适用于任何易变资源.


当你只关心那个时刻的权限时,权限是否是易变的并不重要.应该始终处理失败,但是如果您检查了读取权限但它不在那里,那么您可能希望跳过读取文件,即使有可能在一秒钟后您可以访问该文件.你必须在某处画线.
究竟.这是竞争条件的典型例子.
在尝试打开它之前,这个答案没有回答"如何检查我是否有权打开文件"的问题.情况很可能是,如果在该实例中不允许权限,则软件将不会尝试读取文件,即使在检查权限之后很可能很好地授予了权限.
korro:无论如何,你必须能够处理失败的错误权限,这使初始检查变得多余和浪费.
初始检查可以帮助优雅地处理常见的特定错误 - 向前看通常比将特定异常属性与特定原因匹配更容易.try/catch仍然是强制性的.
好信息,但是,我绝对不同意额外检查是浪费的。这就像说对预期故障的任何检查都是浪费的,而是让其失败并恢复。在C#中(与许多其他支持异常的语言一样),流行的范例是为不可恢复的故障保留了异常。通常,异常代码比异常前测试异常慢。

2> Ash..:

对于遇到类似问题的其他人来说,快速提示:

注意DropBox等Web同步应用.我只花了2个小时思考.NET中的"使用"语句(Dispose模式).

我最终意识到Dropbox不断在后台读取和写入文件,以便同步它们.

猜猜我的Visual Studio Projects文件夹位于何处?当然在"我的Dropbox"文件夹里面.

因此,当我在调试模式下运行我的应用程序时,DropBox也不断访问它正在读取和写入的文件,以便与DropBox服务器同步.这导致锁定/访问冲突.

所以至少我现在知道我需要一个更强大的文件打开功能(即TryOpen()将进行多次尝试).我很惊讶它不是框架的内置部分.

[更新]

这是我的助手功能:

/// 
/// Tries to open a file, with a user defined number of attempt and Sleep delay between attempts.
/// 
/// The full file path to be opened
/// Required file mode enum value(see MSDN documentation)
/// Required file access enum value(see MSDN documentation)
/// Required file share enum value(see MSDN documentation)
/// The total number of attempts to make (multiply by attemptWaitMS for the maximum time the function with Try opening the file)
/// The delay in Milliseconds between each attempt.
/// A valid FileStream object for the opened file, or null if the File could not be opened after the required attempts
public FileStream TryOpen(string filePath, FileMode fileMode, FileAccess fileAccess,FileShare fileShare,int maximumAttempts,int attemptWaitMS)
{
    FileStream fs = null;
    int attempts = 0;

    // Loop allow multiple attempts
    while (true)
    {
        try
        {
            fs = File.Open(filePath, fileMode, fileAccess, fileShare);

            //If we get here, the File.Open succeeded, so break out of the loop and return the FileStream
            break;
        }
        catch (IOException ioEx)
        {
            // IOExcception is thrown if the file is in use by another process.

            // Check the numbere of attempts to ensure no infinite loop
            attempts++;
            if (attempts > maximumAttempts)
            {
                // Too many attempts,cannot Open File, break and return null 
                fs = null;
                break;
            }
            else
            {
                // Sleep before making another attempt
                Thread.Sleep(attemptWaitMS);

            }

        }

    }
    // Reutn the filestream, may be valid or null
    return fs;
}


@Ravisha,你有没有读过Joel最受欢迎的答案?正如乔尔所说,"你所做的只是尝试打开文件,如果失败则处理异常"**.请不要因为你不喜欢无法避免的事实而进行投票.
@Ash我认为你没有正确地阅读问题他希望避免尝试捕获.
推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有