Condividi tramite


Accesso rapido alle proprietà dei file in WinUI

Informazioni su come raccogliere rapidamente un elenco di file e le relative proprietà da una raccolta e usare tali proprietà in un'app.  

Prerequisiti

Uso

Molte app devono elencare le proprietà di un gruppo di file, ma non devono sempre interagire direttamente con i file. Ad esempio, un'app musicale riproduce (apre) un file alla volta, ma richiede le proprietà di tutti i file in una cartella in modo che l'app possa visualizzare la coda dei brani o in modo che l'utente possa scegliere un file valido da riprodurre.

Gli esempi in questa pagina non devono essere usati nelle app che modificheranno i metadati di ogni file o app che interagiscono con tutti i File di archiviazione risultanti oltre a leggerne le proprietà. Per altre informazioni, vedere Enumerare ed eseguire query su file e cartelle

Enumerare tutte le immagini in una posizione

In questo esempio verrà illustrato come

  • Compilare un oggetto QueryOptions per specificare che l'app vuole enumerare i file il più rapidamente possibile.
  • Recuperare le proprietà del file eseguendo il paging degli oggetti StorageFile nell'app. Il paging dei file in riduce la memoria usata dall'app e migliora la velocità di risposta percepita.

Creazione della query

Per compilare la query, usiamo un oggetto QueryOptions per specificare che l'app è interessata a enumerare solo determinati tipi di file di immagini e per filtrare i file protetti con Windows Information Protection (System.Security.EncryptionOwners). 

È importante impostare le proprietà a cui l'app accede tramite QueryOptions.SetPropertyPrefetch. Se l'app accede a una proprietà non precaricata, si verificherà una penalizzazione significativa delle prestazioni.

L'impostazione di IndexerOption.OnlyUseIndexerAndOptimzeForIndexedProperties indica al sistema di restituire i risultati il più rapidamente possibile, ma includere solo le proprietà specificate in SetPropertyPrefetch.

Impaginazione nei risultati

Gli utenti possono avere migliaia o milioni di file nella raccolta immagini, quindi la chiamata a GetFilesAsync sovraccarica il computer perché crea un oggetto StorageFile per ogni immagine. Questo problema può essere risolto creando un numero fisso di File di archiviazione contemporaneamente, elaborandoli nell'interfaccia utente e quindi rilasciando la memoria. 

In questo esempio si usa StorageFileQueryResult.GetFilesAsync(UInt32 StartIndex, UInt32 maxNumberOfItems) per recuperare solo 100 file alla volta. L'app elabora quindi i file e consente al sistema operativo di rilasciare tale memoria in seguito. Questa tecnica limiterà la memoria massima dell'app e garantisce che il sistema rimanga reattivo. Naturalmente, è necessario modificare il numero di file restituiti per lo scenario, ma per garantire un'esperienza reattiva per tutti gli utenti, è consigliabile non recuperare più di 500 file contemporaneamente.

Esempio

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); 
} 

Risultati

I file StorageFile risultanti contengono solo le proprietà richieste, ma vengono restituiti 10 volte più velocemente rispetto agli altri IndexerOptions. L'app può comunque richiedere l'accesso alle proprietà non già incluse nella query, ma esiste una riduzione delle prestazioni per aprire il file e recuperare tali proprietà.  

Aggiunta di cartelle alle librerie

Le app possono richiedere all'utente di aggiungere il percorso all'indice usando StorageLibrary.RequestAddFolderAsync. Una volta inclusa la posizione, verrà automaticamente indicizzata e le app potranno utilizzare questa tecnica per enumerare i file.  

Vedere anche

Informazioni di riferimento sulle API QueryOptions
Enumerare e consultare file e cartelle
Autorizzazioni di accesso ai file