简体   繁体   中英

How to get only the files that are possible to copy?

I have this line of code: (using LINQ)

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

But sometimes my program finds protected files, such as system files or even system folders that can't be opened.

How can I surpass this problem:

Only get file name of open/free files-folders.

You can't tell, you just have to catch the exception.

What if the file is free when doing the free check, but in use when processing?

That can be a problem. If it throws an exception when going through the directories, it stops.

If you want to ignore those directories and keep going, you have to write a recursive method to do it:

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;
}

A somewhat more memory efficient version would be:

    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;
    }

you could use something like this, potentially you will have to tweak attribute check:

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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM