Search code examples
uwpgetfiles

UWP - How to reliably get files from folder?


If a folder contains many files (>300..1000), and the disk drive is not very fast, then I can't get the code to reliably load the full list of files. First it loads a few files (like 10 or 100, depending on the Moon position). The next attempts (of runnin the same code) return slightly more, for example 200, but there is no guarantee this number will grow.

I have tried many variants, including:

res = new List<StorageFile>(await query.GetFilesAsync());

and:

public async static Task<List<StorageFile>> GetFilesInChunks(
    this StorageFileQueryResult query)
{
        List<StorageFile> res = new List<StorageFile>();
        List<StorageFile> chunk = null;
        uint chunkSize = 200;
        bool isLastChance = false;

        try
        {
            for (uint startIndex = 0; startIndex < 1000000;)
            {
                var files = await query.GetFilesAsync(startIndex, chunkSize);
                chunk = new List<StorageFile>(files);

                res.AddRange(chunk);

                if (chunk.Count == 0)
                {
                    if (isLastChance)
                        break;
                    else
                    {
                        /// pretty awkward attempt to rebuild the query, but this doesn't help too much :)                          
                        await query.GetFilesAsync(0, 1);

                        isLastChance = true;
                    }
                }
                else
                    isLastChance = false;

                startIndex += (uint)chunk.Count;
            }
        }
        catch
        {
        }

        return res;
    }

This code looks a bit complex, but I had already tried its simpler variants :(

Would be glad to get your help on this..


Solution

  • How to reliably get files from folder?

    The recommended way to enumerate a large number of files is to use the batching functionality on GetFilesAsync to page in groups of files as they’re needed. This way, your app can do background processing on the files while it’s waiting for the next set to be created.

    example

    uint index = 0, stepSize = 10;
    IReadOnlyList<StorageFile> files = await queryResult.GetFilesAsync(index, stepSize);
    index += 10;   
    while (files.Count != 0)
    {
      var fileTask = queryResult.GetFilesAsync(index, stepSize).AsTask();
      foreach (StorageFile file in files)
      {
        // Do the background processing here   
      }
      files = await fileTask;
      index += 10;
    }
    

    The extension method of StorageFileQueryResult that you made is similar to above.

    However, the reliably of getting files does not depend on the above, it depends on QueryOptions.

    options.IndexerOption = IndexerOption.OnlyUseIndexer;
    

    If you use OnlyUseIndexer,it will query very quickly. But the query result may not be complete. The reason is that some files have not yet been indexed in the system.

    options.IndexerOption = IndexerOption.DoNotUseIndexer;
    

    If you use DoNotUseIndexer,it will query slowly. And the query result is complete.

    This blog tells the Accelerate File Operations with the Search Indexer in detail. Please refer to.