How to get all files in a StorageFolder in Windows

2019-05-11 06:19发布

问题:

I want to get all files in a folder and its sub folders. but a flat query like this:

var allFiles = await myFolder.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByName);

throws a ArgumentException exception:

A first chance exception of type 'System.ArgumentException' occurred

Additional information: Value does not fall within the expected range.

before I query subfolders one by one, isn't there any other way?

回答1:

You want all the files and folder which are a descendent of the root folder, not just the shallow enummeration. For most folders the only way to enumerate all the contents and its subfolders content is:

  1. Use StorageFolder.GetFilesAsync() for the files
  2. Use StorageFolder.GetFoldersAsync() to retrieve the all the subfolders
  3. Repeat recursively for all the subfolders you find in step 2.

There is a workaround for this if you are looking for a particular type of media. The instructions are here. These few combinations of locations and CommonFile/FolderQuery options will give a device deep search for media and return the ordered results.



回答2:

Use CommonFileQuery.OrderByName This is a deep query too so the result will contain all of files from all of subfolders AND IT WORKS! ;)



回答3:

MSDN says that you get System.ArgumentException if:

You specified a value other than DefaultQuery from the CommonFileQuery enumeration for a folder that's not a library folder.

https://msdn.microsoft.com/en-us/library/windows/apps/BR211591.aspx



回答4:

That is strange! Looks like a bug in GetFilesAsync method with all CommaonFileQuery options except DefaultQuery. It is working fine with DefaultQuery.

  var allFiles = await myFolder.GetFilesAsync(CommonFileQuery.DefaultQuery);

Hope this helps!



回答5:

I had the same problem, solved it by preloading file paths recursively:

private static List<string> mContentFilenames = new List<string>();


private static void preloadContentFilenamesRecursive(StorageFolder sf)
{
    var files = sf.GetFilesAsync().AsTask().ConfigureAwait(false).GetAwaiter().GetResult();
    if (files != null)
    {
        foreach (var f in files)
        {
            mContentFilenames.Add(f.Path.Replace('\\','/'));
        }
    }
    var folders = sf.GetFoldersAsync().AsTask().ConfigureAwait(false).GetAwaiter().GetResult();
    if (folders != null)
    {
        foreach (var f in folders)
        {
            preloadContentFilenamesRecursive(f);
        }
    }

}

private static void preloadContentFilenames()
{
    if (mContentFilenames.Count > 0)
        return;
    var installed_loc = Windows.ApplicationModel.Package.Current.InstalledLocation;
    var content_folder = installed_loc.GetFolderAsync("Content").AsTask().ConfigureAwait(false).GetAwaiter().GetResult();
    if (content_folder != null)
        preloadContentFilenamesRecursive(content_folder);
}

private static bool searchContentFilename(string name)
{
    var v = from val in mContentFilenames where val.EndsWith(name.Replace('\\', '/')) select val;
    return v.Any();
}

No idea why downvoted, there is no other way to get full filelist in WP8.1. MSFT for some strange reason corrupts its apis from version to version. Some of calls now returns "not implemented".