How to get all files in a StorageFolder in Windows

2019-05-11 05:28发布

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?

5条回答
叼着烟拽天下
2楼-- · 2019-05-11 06:20

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

查看更多
Rolldiameter
3楼-- · 2019-05-11 06:30

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!

查看更多
唯我独甜
4楼-- · 2019-05-11 06:33

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

查看更多
Bombasti
5楼-- · 2019-05-11 06:33

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".

查看更多
仙女界的扛把子
6楼-- · 2019-05-11 06:34

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.

查看更多
登录 后发表回答