尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

UWP 文件夹枚举与分组查询实战:解读 Windows-universal-samples 的 FolderEnumeration 示例

UWP 文件夹枚举与分组查询实战:解读 Windows-universal-samples 的 FolderEnumeration 示例 示例工程【免费下载链接】Windows-universal-samplesAPI samples for the Universal Windows Platform.项目地址https://gitcode.com/gh_mirrors/wi/Windows-universal-samples点击查看免费下载导读本指南以 Windows-universal-samples 仓库中归档的 FolderEnumeration 示例archived/FolderEnumeration/README.md为核心系统讲解 UWP 应用如何基于Windows.Storage与Windows.Storage.Search命名空间完成四类典型任务枚举位置文件夹、设备、网络位置的顶层文件与子文件夹、按分组查询整个位置内的全部文件、在查询结果中预取文件属性与缩略图、以及展示文件的存储提供程序与离线可用性。读完本文你将掌握StorageFolder、StorageFolderQueryResult、QueryOptions、CommonFolderQuery等核心 API 的实际用法并能直接对照仓库中 C#、C/CX、C/WinRT 与 JavaScript 四种语言的完整实现进行二次开发。示例概览一份文档四种语言四个场景FolderEnumeration 示例的目标非常聚焦枚举某个位置如文件夹、设备或网络位置内部的顶层文件与文件夹并通过查询按文件组file groups枚举该位置内的所有文件。它被归档在 archived/FolderEnumeration 目录下JavaScript 实现同时在 Samples/FolderEnumeration 目录下保留着当前维护的 C#cs/、C/CXcpp/与 C/WinRTcppwinrt/版本。从源码结构看四个语言版本在场景划分上完全对齐每个场景对应一个独立的页面与代码文件场景核心任务C# 实现C/CX 实现C/WinRT 实现JavaScript归档Scenario 1枚举顶层文件与子文件夹cs/Scenario1.xaml.cscpp/Scenario1.xaml.cppcppwinrt/Scenario1.cppjs/js/scenario1.jsScenario 2按月份/评分/标签分组枚举全部文件cs/Scenario2.xaml.cs—cppwinrt/Scenario2.cppjs/js/scenario2.jsScenario 3查询结果中预取文件属性与缩略图cs/Scenario3.xaml.cs——js/js/scenario3.jsScenario 4展示文件提供程序与可用性cs/Scenario4.xaml.cs——js/js/scenario4.js归档文档本身即明确了示例所依赖的两大核心命名空间Windows.Storage提供StorageFolder、StorageFile等对象模型与Windows.Storage.Search提供StorageFolderQueryResult、QueryOptions、CommonFolderQuery、CommonFileQuery等查询能力这与仓库中各语言源码顶部的using/#include声明完全吻合。前置准备系统要求与库访问能力归档文档给出了明确的运行与构建前提并在各语言版本的Package.appxmanifest中得到了印证运行环境Windows 10 build 10500 或更高版本Windows Server 2016 Technical Preview build 10500 或更高版本Windows Phone 同样要求 Windows 10 build 10500 及以上。当前维护版 Samples/FolderEnumeration/README.md 中标注的系统要求为 Windows 10 build 10586。开发工具Visual Studio 2017归档版本要求当前维护版本要求 Visual Studio 与 Windows 10 即可构建执行。库访问能力示例访问图片库Pictures library因此必须在应用清单中声明picturesLibrary能力。这一点在 cs/Package.appxmanifest 与 js/Package.appxmanifest 的Capabilities节点中均有明确声明Capabilities uap:Capability NamepicturesLibrary / /Capabilities缺少该声明时KnownFolders.GetFolderForUserAsync获取图片库将失败这是运行示例前必须检查的第一项配置。场景一枚举位置的顶层文件与子文件夹归档文档描述的第一个任务是使用StorageFolder.GetFilesAsync与StorageFolder.GetFoldersAsync两个方法枚举某个位置示例中为图片库仅顶层immediate children的文件与文件夹。C# 实现cs/Scenario1.xaml.cs 展示了完整的调用链StorageFolder picturesFolder await KnownFolders.GetFolderForUserAsync(null /* current user */, KnownFolderId.PicturesLibrary); IReadOnlyListStorageFile fileList await picturesFolder.GetFilesAsync(); IReadOnlyListStorageFolder folderList await picturesFolder.GetFoldersAsync(); var count fileList.Count folderList.Count; StringBuilder outputText new StringBuilder(picturesFolder.Name ( count )\n\n); foreach (StorageFolder folder in folderList) { outputText.AppendLine( folder.DisplayName \\); } foreach (StorageFile file in fileList) { outputText.AppendLine( file.Name); }要点拆解KnownFolders.GetFolderForUserAsync(null, KnownFolderId.PicturesLibrary)null表示当前用户返回代表图片库的StorageFolder。该 API 同样出现在 C/WinRT 与 JavaScript 版本中是三种语言共用的入口。GetFilesAsync()/GetFoldersAsync()分别只返回直接位于该文件夹下的文件与子文件夹不递归深入子目录。子文件夹使用DisplayName显示并附加\后缀文件使用Name用于在 UI 上区分目录项与文件项。C/WinRT 实现cppwinrt/Scenario1.cpp 使用协程与co_await编写了语义等价、异步非阻塞的实现StorageFolder picturesFolder co_await KnownFolders::GetFolderForUserAsync(nullptr /* current user */, KnownFolderId::PicturesLibrary); IVectorViewStorageFile fileList co_await picturesFolder.GetFilesAsync(); IVectorViewStorageFolder folderList co_await picturesFolder.GetFoldersAsync(); uint32_t count fileList.Size() folderList.Size(); std::wstringstream output; output std::wstring_view{ picturesFolder.Name() } L ( count L)\n\n; for (StorageFolder const folder : folderList) { output L std::wstring_view{ folder.DisplayName() } L\\ std::endl; } for (StorageFile const file : fileList) { output L std::wstring{ file.Name() } std::endl; } OutputTextBlock().Text(output.str());C/CX 版本cpp/Scenario1.xaml.cpp则使用concurrency::create_task链式组合异步操作三种 C 风格可以对照学习C/CX 的任务延续task continuation、C/WinRT 的协程、C# 的async/await本质上是同一异步模型的三种表达。JavaScript 实现归档的 js/js/scenario1.js 使用 WinJS Promise 风格并调用picturesLibrary.getItemsAsync()一次性获取全部顶层项再通过item.isOfType(Windows.Storage.StorageItemTypes.folder)区分文件夹与文件Windows.Storage.KnownFolders.getFolderForUserAsync(null, Windows.Storage.KnownFolderId.picturesLibrary).then(function (picturesLibrary) { group outputResultGroup(picturesLibrary.name); return picturesLibrary.getItemsAsync(); }).done(function (items) { outputItems(group, items); });值得注意C#/C 版本刻意将文件与文件夹分两次异步调用GetFilesAsync与GetFoldersAsync而 JS 版本用一次getItemsAsync()合并获取随后按类型分类显示——两种写法均可前者在只需文件或只需文件夹时更省开销。场景二按分组查询位置内的全部文件归档文档描述的核心概念是file groups文件组使用StorageFolder.CreateFolderQueryWithOptions将位置图片库中包括子文件夹在内的全部文件按你指定的条件如评分 rating排序成组每组是一个由StorageFolderQueryResult.GetFoldersAsync返回的虚拟文件夹同样以StorageFolder对象表示——组内所有文件共享你指定的共同特征。三种分组条件cs/Scenario2.xaml.cs 提供了三个按钮分别演示CommonFolderQuery枚举的三个取值// 按拍摄月份分组 await GroupByHelperAsync(new QueryOptions(CommonFolderQuery.GroupByMonth)); // 按评分分组 await GroupByHelperAsync(new QueryOptions(CommonFolderQuery.GroupByRating)); // 按标签分组 await GroupByHelperAsync(new QueryOptions(CommonFolderQuery.GroupByTag));查询与结果消费GroupByHelperAsynccs/Scenario2.xaml.cs演示了完整的查询流水线StorageFolder picturesFolder await KnownFolders.GetFolderForUserAsync(null /* current user */, KnownFolderId.PicturesLibrary); StorageFolderQueryResult queryResult picturesFolder.CreateFolderQueryWithOptions(queryOptions); IReadOnlyListStorageFolder folderList await queryResult.GetFoldersAsync(); foreach (StorageFolder folder in folderList) { IReadOnlyListStorageFile fileList await folder.GetFilesAsync(); // 以 组名 (文件数) 作为标题逐文件列出 }三步流程可概括为构造QueryOptions传入CommonFolderQuery枚举值决定分组维度创建查询picturesFolder.CreateFolderQueryWithOptions(queryOptions)返回StorageFolderQueryResult取结果queryResult.GetFoldersAsync()返回一组虚拟文件夹每个虚拟文件夹再GetFilesAsync()展开其成员文件。C/WinRT 版本cppwinrt/Scenario2.cpp在接口使用上完全一致仅将QueryOptions(CommonFolderQuery::GroupByMonth)等枚举改为 C/WinRT 命名空间形式。JavaScript 归档版本js/js/scenario2.js使用picturesLibrary.createFolderQuery(Windows.Storage.Search.CommonFolderQuery.groupByMonth)创建查询并用WinJS.Promise.join聚合多个folder.getFilesAsync()的 Promise确保所有分组按顺序显示var promises folders.map(function (folder) { return folder.getFilesAsync(); }); WinJS.Promise.join(promises).done(function (folderContents) { for (var i in folderContents) { var group outputResultGroup(folders.getAt(i).name); outputItems(group, folderContents[i]); } });设计含义从实现可以推断CommonFolderQuery分组查询的价值它让系统而非应用负责跨子目录收集与归类文件应用只需消费分组结果。典型的应用场景包括相册按月份归档、媒体库按流派分类等。归档文档特别指出CommonFolderQuery与CommonFileQuery枚举是示例中额外的重要 API后者用于文件级查询的排序维度如OrderByName在场景三中会用到。场景三查询结果中预取文件属性与缩略图第三个任务引入性能优化手段在创建查询时通过QueryOptions.SetPropertyPrefetch指定要预取的属性系统会在索引阶段提前抓取之后访问这些属性时无需逐文件异步等待SetThumbnailPrefetch对缩略图同理。归档文档同时提醒预取可能延长查询执行时间但会让大量文件信息访问更高效——这是典型的以查询耗时换遍历效率的取舍。属性预取配置cs/Scenario3.xaml.cs 的配置流程// 文件类型过滤器只查询图片 Liststring fileTypeFilter new Liststring(); fileTypeFilter.Add(.jpg); fileTypeFilter.Add(.png); fileTypeFilter.Add(.bmp); fileTypeFilter.Add(.gif); // 构造查询选项按名称排序 类型过滤 var queryOptions new QueryOptions(CommonFileQuery.OrderByName, fileTypeFilter); // 预取顶层属性使用 PropertyPrefetchOptions附加属性使用字符串列表 Liststring propertyNames new Liststring(); propertyNames.Add(System.Copyright); // 版权 propertyNames.Add(System.Image.ColorSpace); // 色彩空间 queryOptions.SetPropertyPrefetch(PropertyPrefetchOptions.ImageProperties, propertyNames); // 缩略图预取按需启用例如构建相册网格视图时 /* const uint requestedSize 190; const ThumbnailMode thumbnailMode ThumbnailMode.PicturesView; const ThumbnailOptions thumbnailOptions ThumbnailOptions.UseCurrentScale; queryOptions.SetThumbnailPrefetch(thumbnailMode, requestedSize, thumbnailOptions); */参数含义PropertyPrefetchOptions.ImagePropertiesPropertyPrefetchOptions枚举值代表一组顶层属性尺寸、日期等图片常用属性可与其他选项按位组合附加属性列表以 Windows 系统属性名如System.Copyright、System.Image.ColorSpace补充预取SetThumbnailPrefetch(mode, requestedSize, options)ThumbnailMode决定缩略图用途示例用PicturesViewrequestedSize为请求边长示例为 190 像素ThumbnailOptions控制生成行为示例用UseCurrentScale。JavaScript 归档版本js/js/scenario3.js以search.QueryOptions(search.CommonFileQuery.orderByName, fileTypeFilter)构造选项queryOptions.setPropertyPrefetch(imageProperties, additionalProperties)完成同样的预取声明并把缩略图预取同样保留为注释块说明它是按需开启的可选项。消费预取结果预取的效果体现在结果消费阶段cs/Scenario3.xaml.csvar query picturesFolder.CreateFileQueryWithOptions(queryOptions); IReadOnlyListStorageFile fileList await query.GetFilesAsync(); foreach (StorageFile file in fileList) { // 预取成功时GetImagePropertiesAsync 会同步返回 var properties await file.Properties.GetImagePropertiesAsync(); // 展示 Dimensions: 宽x高 // 附加属性同理预取完成后可立即返回 IDictionarystring, object extraProperties await file.Properties.RetrievePropertiesAsync(propertyNames); // 读取 System.Copyright 与 System.Image.ColorSpace空值显示 none }关键点GetImagePropertiesAsync()与RetrievePropertiesAsync()在接口上仍是异步方法但当属性已被预取时会近乎立即返回避免了遍历数百个文件时逐次发起磁盘/索引 I/O。这正是归档文档所述预取让大量文件信息访问更高效的机制所在。场景四展示文件提供程序与离线可用性第四个任务把查询对象从固定的图片库扩展到用户任意选取的文件夹并利用StorageFile.Provider与StorageFile.IsAvailable两个属性展示每个文件的存储提供程序provider与离线可用状态。cs/Scenario4.xaml.cs 的实现// 1. 让用户选择文件夹 FolderPicker picker new FolderPicker(); picker.FileTypeFilter.Add(*); picker.ViewMode PickerViewMode.List; picker.SuggestedStartLocation PickerLocationId.DocumentsLibrary; StorageFolder folder await picker.PickSingleFolderAsync(); if (folder ! null) { // 2. 创建默认文件查询并获取全部文件 var query folder.CreateFileQuery(); var fileList await query.GetFilesAsync(); // 3. 逐文件展示 provider 与可用性 foreach (StorageFile file in fileList) { var line file.Name; line : On file.Provider.DisplayName; // 本机、OneDrive、网络或应用内容 line (; line file.IsAvailable ? available : not available; line ); // 输出到 UI } }行为语义FolderPicker的FileTypeFilter加入*表示接受任意文件类型SuggestedStartLocation DocumentsLibrary只影响打开对话框的起始位置用户仍可导航到任意目录——这绕开了picturesLibrary等库能力的限制folder.CreateFileQuery()无参数重载创建覆盖该文件夹含子文件夹全部文件的默认查询file.Provider.DisplayName文件所在存储提供程序的显示名。从源码注释看典型值包括本机This PC、OneDrive、网络位置Network以及应用内容Application Contentfile.IsAvailable指示文件当前是否可用。对于 OneDrive 这类云占位文件联机时或标记为始终离线可用时通常为true否则为false是判断云文件是否可立即读取的直接手段。JavaScript 归档版本js/js/scenario4.js使用Windows.Storage.Pickers.FolderPicker与folder.createFileQuery()完成同样的流程逐项拼接: On file.provider.displayName (available/not available)输出。关键 API 速查归档文档明确列出的额外重要 API及本仓库中的对应用法汇总如下API用途仓库证据CommonFolderQuery文件夹分组维度GroupByMonth、GroupByRating、GroupByTag等cs/Scenario2.xaml.csCommonFileQuery文件查询排序维度如OrderByNamecs/Scenario3.xaml.csPropertyPrefetchOptions顶层属性预取选项如ImagePropertiescs/Scenario3.xaml.csStorageFolderQueryResult分组查询的结果句柄GetFoldersAsync()返回虚拟文件夹cs/Scenario2.xaml.csQueryOptions封装排序、过滤、属性/缩略图预取的查询参数cs/Scenario3.xaml.cs构建与运行归档文档给出了完整的构建与运行步骤适用于 Samples/FolderEnumeration 下的当前版本若通过 ZIP 下载整个示例集合务必解压完整归档不要只解压包含目标示例的文件夹——示例依赖仓库根目录的SharedContent共享资源启动 Visual Studio选择FileOpenProject/Solution在解压目录下进入Samples子目录 → 本示例子目录 → 所选语言子目录C、C# 或 C/WinRT双击其中的解决方案文件.sln如 cs/FolderEnumeration.sln按CtrlShiftB或选择BuildBuild Solution构建。运行分两种方式仅部署选择BuildDeploy Solution部署并运行按F5或选择DebugStart Debugging进行调试运行按CtrlF5或选择DebugStart Without Debugging则不调试直接运行。关联资源归档文档将本示例与仓库内其他文件/文件夹相关主题归为一组可在本仓库中继续深入当前维护版本说明Samples/FolderEnumeration/README.md标注了该示例面向 C#、C/CX、C/WinRT 三种语言并链接回归档的 JavaScript 版本程序化文件搜索Samples/FileSearch文件访问Samples/FileAccess文件与文件夹缩略图Samples/FileThumbnails核心命名空间Windows.Storage与Windows.Storage.Search的用法均可直接对照上述示例源码与 archived/FolderEnumeration/js 目录下的全部 JavaScript 页面实现学习。需要注意的是归档版本JavaScript与当前维护版本C#/C/C/WinRT在场景划分与 API 调用上一一对应四种语言实现互为翻译参照是学习 UWP 异步编程与文件系统查询 API 的极佳对照样本。赞分享示例工程【免费下载链接】Windows-universal-samplesAPI samples for the Universal Windows Platform.项目地址https://gitcode.com/gh_mirrors/wi/Windows-universal-samples点击查看免费下载相关推荐FolderEnumeration 示例全解析基于 Windows.Storage 与 Windows.Storage.Search 的 UWP 文件夹枚举与查询实战FolderEnumeration 示例全解析基于 Windows.Storage 与 Windows.Storage.Search 的 UWP 文件夹枚举与示例工程Windows UWP DPI 缩放实战解读 Windows-universal-samples 的 DpiScaling 示例Windows UWP DPI 缩放实战解读 Windows universal samples 的 DpiScaling 示例 导读 本文基于 Window示例工程UWP 文件访问实战解读 Windows-universal-samples FileAccess 示例的 11 个文件操作场景UWP 文件访问实战解读 Windows universal samples FileAccess 示例的 11 个文件操作场景 本篇文章围绕 Windows示例工程上一篇FerretDB 遥测机制全解析数据采集范围、telemetry.json 结构与开启/禁用实操指南下一篇Hearthstone-Script深度解析炉石传说智能脚本的5大核心价值与实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表