Szybki dostęp do właściwości pliku w usłudze WinUI

Dowiedz się, jak szybko zebrać listę plików i ich właściwości z biblioteki oraz użyć tych właściwości w aplikacji.  

Wymagania wstępne

Użycie

Wiele aplikacji musi wyświetlić listę właściwości grupy plików, ale nie zawsze trzeba bezpośrednio korzystać z plików. Na przykład aplikacja muzyczna odtwarza (otwiera) jeden plik naraz, ale potrzebuje właściwości wszystkich plików w folderze, aby aplikacja mogła wyświetlić kolejkę piosenek, lub aby użytkownik mógł wybrać prawidłowy plik do odtwarzania.

Przykłady na tej stronie nie powinny być używane w aplikacjach, które zmodyfikują metadane każdego pliku lub aplikacji, które współdziałają ze wszystkimi wynikowymi plikami StorageFile poza odczytywaniem ich właściwości. Aby uzyskać więcej informacji, zobacz Enumerate and query files and folders (Wyliczanie i wykonywanie zapytań o pliki i foldery ). 

Wylicz wszystkie zdjęcia w lokalizacji

W tym przykładzie będziemy

  • Skompiluj obiekt QueryOptions , aby określić, że aplikacja chce wyliczyć pliki tak szybko, jak to możliwe.
  • Pobieranie właściwości pliku przez stronicowanie obiektów StorageFile do aplikacji. Stronicowanie plików w programie zmniejsza ilość pamięci używanej przez aplikację i poprawia jego postrzeganą szybkość reakcji.

Tworzenie zapytania

Aby skompilować zapytanie, użyjemy obiektu QueryOptions, aby określić, że aplikacja jest zainteresowana wyliczaniem tylko niektórych typów plików obrazów i filtrowania plików chronionych za pomocą usługi Windows Information Protection (System.Security.EncryptionOwners). 

Ważne jest, aby ustawić właściwości, do których aplikacja będzie uzyskiwać dostęp przy użyciu elementu QueryOptions.SetPropertyPrefetch. Jeśli aplikacja uzyskuje dostęp do właściwości, która nie jest pobierana wstępnie, spowoduje to znaczący wpływ na wydajność.

Ustawienie IndexerOption.OnlyUseIndexerAndOptimzeForIndexedProperties informuje system, aby zwracał wyniki tak szybko, jak to możliwe, ale aby uwzględniać tylko właściwości określone w SetPropertyPrefetch.

Stronicowanie wyników

Użytkownicy mogą mieć tysiące lub miliony plików w bibliotece obrazów, więc wywołanie metody GetFilesAsync przytłoczy ich maszynę, ponieważ tworzy plik StorageFile dla każdego obrazu. Można to rozwiązać, tworząc stałą liczbę plików StorageFiles jednocześnie, przetwarzając je w interfejsie użytkownika, a następnie zwalniając pamięć. 

W naszym przykładzie robimy to przy użyciu polecenia StorageFileQueryResult.GetFilesAsync(UInt32 StartIndex, UInt32 maxNumberOfItems) w celu pobrania tylko 100 plików jednocześnie. Następnie aplikacja przetworzy pliki i zezwoli systemowi operacyjnemu na późniejsze zwolnienie tej pamięci. Ta technika powoduje ograniczenie maksymalnej ilości pamięci aplikacji i gwarantuje, że system będzie reagować. Oczywiście należy dostosować liczbę plików zwracanych w danym scenariuszu, ale w celu zapewnienia dynamicznego środowiska dla wszystkich użytkowników zaleca się, aby nie pobierać więcej niż 500 plików jednocześnie.

Przykład

StorageFolder folderToEnumerate = KnownFolders.PicturesLibrary; 
// Check if the folder is indexed before doing anything. 
IndexedState folderIndexedState = await folderToEnumerate.GetIndexedStateAsync(); 
if (folderIndexedState == IndexedState.NotIndexed || folderIndexedState == IndexedState.Unknown) 
{ 
    // Only possible in indexed directories.  
    return; 
} 
 
QueryOptions picturesQuery = new QueryOptions() 
{ 
    FolderDepth = FolderDepth.Deep, 
    // Filter out all files that have WIP enabled
    ApplicationSearchFilter = "System.Security.EncryptionOwners:[]", 
    IndexerOption = IndexerOption.OnlyUseIndexerAndOptimizeForIndexedProperties 
}; 

picturesQuery.FileTypeFilter.Add(".jpg"); 
string[] otherProperties = new string[] 
{ 
    SystemProperties.GPS.LatitudeDecimal, 
    SystemProperties.GPS.LongitudeDecimal 
}; 
 
picturesQuery.SetPropertyPrefetch(PropertyPrefetchOptions.BasicProperties | PropertyPrefetchOptions.ImageProperties, 
                                    otherProperties); 
SortEntry sortOrder = new SortEntry() 
{ 
    AscendingOrder = true, 
    PropertyName = "System.FileName" // FileName property is used as an example. Any property can be used here.  
}; 
picturesQuery.SortOrder.Add(sortOrder); 
 
// Create the query and get the results 
uint index = 0; 
const uint stepSize = 100; 
if (!folderToEnumerate.AreQueryOptionsSupported(picturesQuery)) 
{ 
    log("Querying for a sort order is not supported in this location"); 
    picturesQuery.SortOrder.Clear(); 
} 
StorageFileQueryResult queryResult = folderToEnumerate.CreateFileQueryWithOptions(picturesQuery); 
IReadOnlyList<StorageFile> images = await queryResult.GetFilesAsync(index, stepSize); 
while (images.Count != 0 || index < 10000) 
{ 
    foreach (StorageFile file in images) 
    { 
        // With the OnlyUseIndexerAndOptimizeForIndexedProperties set, this won't  
        // be async. It will run synchronously. 
        var imageProps = await file.Properties.GetImagePropertiesAsync(); 
 
        // Build the UI 
        log(String.Format("{0} at {1}, {2}", 
                    file.Path, 
                    imageProps.Latitude, 
                    imageProps.Longitude)); 
    } 
    index += stepSize; 
    images = await queryResult.GetFilesAsync(index, stepSize); 
} 

Wyniki

Wynikowe pliki StorageFile zawierają żądane właściwości, ale są zwracane 10 razy szybciej w porównaniu z innymi elementami IndexerOptions. Aplikacja nadal może zażądać dostępu do właściwości, które nie zostały jeszcze uwzględnione w zapytaniu, ale otwarcie pliku i pobranie tych właściwości wiąże się ze spadkiem wydajności.  

Dodawanie folderów do bibliotek

Aplikacje mogą zażądać od użytkownika dodania lokalizacji do indeksu przy użyciu polecenia StorageLibrary.RequestAddFolderAsync. Po dołączeniu lokalizacji zostanie ona automatycznie zindeksowana, a aplikacje mogą używać tej techniki do wyliczania plików.  

Zobacz także

Dokumentacja interfejsu API QueryOptions
Wyliczanie i wykonywanie zapytań dotyczących plików i folderów
Uprawnienia dostępu do plików