Fast way to retrieve file sizes in a folder in UWP

Viewed 114

I want to sum all file sizes in my application's TempState folder using below code which works fine.

const auto tempFolder { ApplicationData::Current().TemporaryFolder() };
int64_t size { 0 };

const QueryOptions options { CommonFolderQuery::DefaultQuery };
options.FolderDepth(FolderDepth::Shallow);
options.IndexerOption(IndexerOption::UseIndexerWhenAvailable);
options.SetPropertyPrefetch(PropertyPrefetchOptions::BasicProperties, {});

try
{
    for (auto item : co_await tempFolder.CreateFileQueryWithOptions(options).GetFilesAsync())
    {
        size += (co_await item.GetBasicPropertiesAsync()).Size();
    }

    // do something with the size
}
catch (winrt::hresult_error& err)
{
    // ...
}

I currently have just short of 3000 items in the TempState folder and above code takes 20 seconds to compute the sum of file sizes. There needs to be a way to speed this up, right?


What I've tried so far is using

options.IndexerOption(IndexerOption::OnlyUseIndexerAndOptimizeForIndexedProperties);

but then GetFilesAsync returns no files at all.


What can be done to (drastically) improve performance here?

2 Answers

I would prefer a more C++/WinRT way, but my current workaround is to simply #include <filesystem> and to then use

const auto tempFolder { ApplicationData::Current().TemporaryFolder() };
int64_t size { 0 };

for (const auto& file : std::filesystem::directory_iterator(winrt::to_string(tempFolder.Path())))
{
    size += std::filesystem::file_size(file.path().string());
}

which runs in an instant.

IndexerOption.OnlyUseIndexer is best used when returning no results is better than waiting for a slow file operation. The system will return zero results if the indexer is disabled, but will return quickly, still letting apps be reactive to the user. But in your scenario, it is not suitable.

A recommended way to enumerate a large number of files is to use the batching functionality on GetFilesAsync to page in groups of files instead of directly getting all of them at once. Like it is mentioned in this document: Windows 10 - Accelerate File Operations with the Search Indexer. You could check the c# sample code about how to implement the batching functionality and convert it into C++/winrt.

Related