UWP의 파일 속성에 빠르게 액세스Fast access to file properties in UWP 

라이브러리에서 파일 및 속성 목록을 신속하게 수집하고 앱에서 해당 속성을 사용하는 방법에 대해 알아봅니다.Learn how to quickly gather a list of files and their properties from a library and use those properties in an app.  

필수 구성 요소Prerequisites 

  • UWP(유니버설 Windows 플랫폼) 앱에 대한 비동기 프로그래밍   C# 또는 Visual Basic에서 비동기 앱을 작성하는 방법에 대한 자세한 내용은 C# 또는 Visual Basic에서 비동기 API 호출을 참조하세요.Asynchronous programming for Universal Windows Platform (UWP) apps   You can learn how to write asynchronous apps in C# or Visual Basic, see Call asynchronous APIs in C# or Visual Basic. C++에서 비동기 앱을 작성하는 방법은 C++의 비동기 프로그래밍을 참조하세요.To learn how to write asynchronous apps in C++, see Asynchronous programming in C++. 
  • 라이브러리에 대한 액세스 권한   이 예제의 코드에는 picturesLibrary 기능이 필요하지만, 파일 위치에는 다른 기능이 필요하거나 기능이 전혀 필요하지 않을 수 있습니다.Access permissions to Libraries   The code in these examples requires the picturesLibrary capability, but your file location may require a different capability, or no capability at all. 자세한 내용은 파일 액세스 권한을 참조하세요.To learn more, see File access permissions. 
  • 단순 파일 열거    이 예제에서는 QueryOptions를 사용하여 몇 가지 고급 열거 속성을 설정합니다.Simple file enumeration    This example uses QueryOptions to set a few advanced enumeration properties. 작은 디렉터리에 대한 단순 파일 목록을 가져오는 방법에 대한 자세한 내용은 파일 및 폴더 열거 및 쿼리를 참조하세요.To learn more about just getting a simple list of files for a smaller directory, see Enumerate and query files and folders. 


많은 경우 앱이 파일 그룹의 속성을 나열해야 하지만 항상 파일과 직접 상호 작용할 필요는 없습니다.Many apps need to list the properties of a group of files, but don't always need to interact with the files directly. 예를 들어, 뮤직 앱은 한 번에 하나의 파일을 재생하지만(열지만), 앱이 곡 대기열을 표시하거나 사용자가 유효한 재생 파일을 선택할 수 있도록 하기 위해 폴더의 모든 파일에 대한 속성이 필요합니다.For example, a music app plays (opens) one file at a time, but it needs the properties of all of the files in a folder so the app can show the song queue, or so the user can choose a valid file to play.

모든 파일의 메타데이터를 수정할 앱 또는 속성을 읽지 않고 모든 결과 StorageFiles와 상호 작용하는 앱에 이 페이지의 예제를 사용해서는 안 됩니다.The examples on this page shouldn't be used in apps that will modify the metadata of every file or apps that interact with all the resulting StorageFiles beyond reading their properties. 자세한 내용은 파일 및 폴더 열거 및 쿼리를 참조하세요.See Enumerate and query files and folders for more information. 

한 위치에 모든 사진 열거Enumerate all the pictures in a location 

이 예제에서는In this example, we will

  • QueryOptions 개체를 빌드하여 앱이 가능한 빨리 파일을 열거하도록 지정합니다.Build a QueryOptions object to specify that the app wants to enumerate the files as quickly as possible.
  • StorageFile 개체를 앱으로 페이징하여 파일 속성을 가져옵니다.Fetch file properties by paging StorageFile objects into the app. 파일을 페이징하면 앱에서 사용하는 메모리가 줄고 응답 속도가 빨라집니다.Paging the files in reduces the memory used by the app and improves its perceived responsiveness.

쿼리 만들기Creating the query 

쿼리를 작성하기 위해, QueryOptions 개체를 사용하여 앱이 특정 유형의 이미지 파일만 열거하고 Windows Information Protection(System.Security.EncryptionOwners)으로 보호된 파일을 필터링하도록 지정합니다.To build the query, we use a QueryOptions object to specify that the app is interested in enumerating only certain types of images files and to filter out files protected with Windows Information Protection (System.Security.EncryptionOwners). 

QueryOptions.SetPropertyPrefetch를 사용하여 앱이 액세스할 속성을 설정하는 것이 중요합니다.It is important to set the properties the app is going to access using QueryOptions.SetPropertyPrefetch. 앱이 프리페치되지 않은 속성에 액세스할 경우 상당한 성능 저하가 발생합니다.If the app accesses a property that isn’t prefetched, it will incur a significant performance penalty.

IndexerOption.OnlyUseIndexerAndOptimzeForIndexedProperties를 설정하면 결과를 가능한 빨리 반환하되 SetPropertyPrefetch에 지정된 속성만 포함하도록 지정합니다.Setting IndexerOption.OnlyUseIndexerAndOptimzeForIndexedProperties tells the system to return results as quickly as possible, but to only include the properties specified in SetPropertyPrefetch.

결과 페이징Paging in the results 

사용자가 사진 라이브러리에 수천, 수백만 개의 파일을 가지고 있을 수 있으므로 GetFilesAsync를 호출하면 각 이미지에 해당하는 StorageFile이 만들어져 시스템에 부담이 될 것입니다.Users may have thousands or millions of files in their pictures library, so calling GetFilesAsync would overwhelm their machine because it creates a StorageFile for each image. 한 번에 고정된 개수의 StorageFile을 생성하고 UI로 처리한 다음, 메모리를 해제하면 이 문제를 해결할 수 있습니다.This can be solved by creating a fixed number of StorageFiles at one time, processing them into the UI, and then releasing the memory. 

이 예제에서는 StorageFileQueryResult.GetFilesAsync(UInt32 StartIndex, UInt32 maxNumberOfItems)를 사용하여 한 번에 100개의 파일만 가져옵니다.In our example, we do this by using StorageFileQueryResult.GetFilesAsync(UInt32 StartIndex, UInt32 maxNumberOfItems) to only fetch 100 files at a time. 그러면 앱이 파일을 처리하고 나중에 OS가 해당 메모리를 해제할 수 있습니다.The app will then process the files and allow the OS to release that memory afterwards. 이 기법은 앱의 최대 메모리 상한을 지정하고, 시스템이 응답을 유지하도록 합니다.This technique caps the maximum memory of the app and ensures the system stays responsive. 물론 시나리오에 반환되는 파일 수를 조정해야 하지만 모든 사용자에게 신속한 응답을 제공하려면 한 번에 500개가 넘는 파일을 가져오지 않는 것이 좋습니다.Of course, you will need to adjust the number of files returned for your scenario, but to ensure a responsive experience for all users, it's recommended to not fetch more than 500 files at one time.


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.  
QueryOptions picturesQuery = new QueryOptions() 
    FolderDepth = FolderDepth.Deep, 
    // Filter out all files that have WIP enabled
    ApplicationSearchFilter = "System.Security.EncryptionOwners:[]", 
    IndexerOption = IndexerOption.OnlyUseIndexerAndOptimizeForIndexedProperties 

string[] otherProperties = new string[] 
picturesQuery.SetPropertyPrefetch(PropertyPrefetchOptions.BasicProperties | PropertyPrefetchOptions.ImageProperties, 
SortEntry sortOrder = new SortEntry() 
    AscendingOrder = true, 
    PropertyName = "System.FileName" // FileName property is used as an example. Any property can be used here.  
// 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"); 
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}", 
    index += stepSize; 
    images = await queryResult.GetFilesAsync(index, stepSize); 


결과로 생성된 StorageFile 파일에는 요청된 속성만 포함되지만 다른 IndexerOptions에 비해 10배 빠릅니다.The resulting StorageFile files only contain the properties requested, but are returned 10 times faster compared to the other IndexerOptions. 앱은 쿼리에 아직 포함되지 않은 속성에 대한 액세스도 요청할 수 있지만 파일을 열고 속성을 검색할 때 성능이 저하될 수 있습니다. The app can still request access to properties not already included in the query, but there is a performance penalty to open the file and retrieve those properties.  

라이브러리에 폴더 추가Adding folders to Libraries 

앱은 StorageLibrary.RequestAddFolderAsync를 통해 사용자에게 색인에 위치를 추가하도록 요청할 수 있습니다.Apps can request the user to add the location to the index using StorageLibrary.RequestAddFolderAsync. 위치가 포함되면 자동으로 인덱싱되고 앱은 이 방법을 사용하여 파일을 열거할 수 있습니다.Once the location is included, it will be automatically indexed and apps can use this technique to enumerate the files.  

참고 항목See also

QueryOptions API 참조QueryOptions API Reference
파일과 폴더 열거 및 쿼리Enumerate and query files and folders
파일 액세스 권한File access permissions