【问题标题】:How to get only the files that are possible to copy?如何只获取可以复制的文件?
【发布时间】:2013-05-17 16:22:22
【问题描述】:

我有这行代码:(使用 LINQ)

//string folder <-- folder browser dialog.
listFiles = Directory.GetFiles(folder, "*.xml",
              SearchOption.AllDirectories).Select(
                    fileName => Path.GetFullPath(fileName)).ToList();

但有时我的程序会找到受保护的文件,例如无法打开的系统文件甚至系统文件夹。

我该如何克服这个问题:

仅获取打开/免费文件夹的文件名。

【问题讨论】:

    标签: c# winforms file .net-3.5


    【解决方案1】:

    你不知道,你只需要捕获异常。

    如果文件在进行空闲检查时是空闲的,但在处理时正在使用怎么办?

    【讨论】:

    • 抛出异常时停止。 :(
    • 然后抓住它,继续。您需要将处理单个文件的代码包装在 try/catch 块中,捕获您知道如何处理的特定异常,然后忽略它。但是,不要捕获基类 Exception
    【解决方案2】:

    这可能是个问题。如果在遍历目录时抛出异常,它将停止。

    如果你想忽略那些目录并继续前进,你必须编写一个递归方法来做到这一点:

    List<string> GetFiles(string folder, string filter)
    {
        List<string> files = new List<string>();
        try
        {
            // get all of the files in this directory
            files.AddRange(Directory.GetFiles(folder, filter));
            // Now recursively visit the directories
            foreach (var dir in Directory.GetDirectories(folder))
            {
                files.AddRange(GetFiles(dir, filter));
            }
        }
        catch (UnauthorizedAccessException)
        {
            // problem accessing this directory.
            // ignore it and move on.
        }
        return files;
    }
    

    一个更节省内存的版本是:

        private List<string> GetFiles(string folder, string filter)
        {
            var files = new List<string>();
    
            // To create a recursive Action, you have to initialize it to null,
            // and then reassign it. Otherwise the compiler complains that you're
            // using an unassigned variable.
            Action<string> getFilesInDir = null;
            getFilesInDir = new Action<string>(dir =>
                {
                    try
                    {
    
                        // get all the files in this directory
                        files.AddRange(Directory.GetFiles(dir, filter));
                        // and recursively visit the directories
                        foreach (var subdir in Directory.GetDirectories(dir))
                        {
                            getFilesInDir(subdir);
                        }
                    }
                    catch (UnauthorizedAccessException)
                    {
                        // ignore exception
                    }
                });
    
            getFilesInDir(folder);
            return files;
        }
    

    【讨论】:

    • 我在“DoWork”(backgroundWorker) 中使用 LINQ,因为这似乎很简单……但我要试试这个。
    【解决方案3】:

    你可以使用这样的东西,可能你必须调整属性检查:

    Directory.GetFiles(folder, "*.xml", SearchOption.AllDirectories)
       .Select(fileName => new FileInfo(Path.GetFullPath(fileName)))
       .Where(n => !n.Attributes.HasFlag(FileAttributes.System))
       .Select(n => n.FullName)
       .ToList();
    

    【讨论】:

    • 这里显示 System.IO.File.Attributes 不包含 HasFlag 的定义...
    • 我在我的 VS2012 上对其进行了测试,它工作正常。自 .NET 4 起,Enum 就实现了 HasFlag - 我认为。您可以使用标准的按位 & 代替。
    • .Where(n => n.Attributes != FileAttributes.System) 受保护的文件夹(例如:Windows 8 中的 WindowsApps)仍然会触发我的捕获。但是谢谢,至少系统文件被处理了。
    猜你喜欢
    • 2014-02-18
    • 2021-05-04
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    • 2021-03-27
    • 2021-12-29
    • 2018-05-25
    相关资源
    最近更新 更多