Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Faster way to get files of a folder than StorageFolder.GetFilesAsync()?

StorageFolder.GetFilesAsync is incredibly slow:

  • ~7 seconds for a folder with ~3500 files

Back in Windows Phone 8.0 Silverlight, I was able to get the content of the CameraRoll much faster (via the MediaLibrary):

  • <1 second for the same amount of files

Are there any possibilities to speedup GetFilesAsync up, or is there any alternative for getting files of a folder?

I need the photo files to immediately extract information such as the Geotag or DateTaken. You can see how fast they loaded with Silverlight in my app GeoPhoto - which I am now trying to port to UWP. I've already implemented caching (mapping geotag and DateTaken with the picture path), so I would only need the picture path for subsequent app starts. Photos not yet cached could then be displayed later (after the long GetFilesAsync-call), but it is important to give the user something he can interact with immediately after he launched the app.

like image 203
tipa Avatar asked Sep 19 '15 13:09

tipa


2 Answers

I wonder if you've read this: https://www.suchan.cz/2014/07/file-io-best-practices-in-windows-and-phone-apps-part-1-available-apis-and-file-exists-checking/

Windows 8.1 - finally on Windows 8.1 the fastest method is the new StorageFolder.TryGetItemAsync method, but only by a slim margin when comparing to other methods. The main benefit here is definitely the simple code required without any Exception catching if the file does not exists. The results for sync methods are similar to Windows 8 platform, if original synchronization context is not required, the sync methods are a better choice.

In short, for checking if target file exists, on WP8 and WP8.1 Silverlight the fastest method is File.Exists, on Windows 8 and WP8.1 XAML you should use StorageFolder.GetFileAsync, and on Windows 8.1 use the new method StorageFolder.TryGetItemAsync. Do NOT use the iteration of StorageFiles returned from StorageFolder.GetFilesAsync on any platform, it is terribly slow. Also if you don't need co continue on the original thread, you can use the synchronous alternatives on WP8.1 XAML, Windows 8 and Windows 8.1 platforms.

or something like this?

StorageFolder.GetItemsAsync(UInt32, UInt32) 

to fetch the first X number of files to give the user immediate feedback that you desire. After that load the rest.

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

like image 88
O.O Avatar answered Oct 03 '22 05:10

O.O


EDIT: Since my original answer seemed not to be helpful, I hope this one will be matching your problem.

I created a folder with ~4000 files, just for testing and used a Stopwatch for taking the time.
Just reading each item in the folder took:

System.IO.Directory.GetFiles(): 0.2 secs

Windows.Storage.StorageFolder.GetFilesAsync ~5.5 secs

Executing both mulitple times and in different order

I understand that this just gives you the file names as string, but depending on the library you use for reading the pictures, this might still help you.

Original Answer:
When you got the Path as string (e.g from ApplicationData.Current.LocalFolder.Path) you may use System.IO.Directory.GetFiles(string path). It does not return specific objects, but the path as string. You can use those with the static class System.IO.File.

It also allows you to pass a searchPattern, which allows you to use placeholders like * and ? and it's working synchronously, but retrieving files via this method works really quick.

like image 31
M. Schmidt Avatar answered Oct 03 '22 05:10

M. Schmidt