Marvin's Blog【程式人生】

Ability will never catch up with the demand for it

19 May 2020

WinRT的StorageFile和StorageFolder

在UWP中,对文件系统的访问时受管控的。WinRT提供了两个代理类,来支持对目录和文件访问:StorageFolder 和StorageFile。

StorageFolder 可以从路径生成,也就是GetFolderFromPathAsync,或者通过用户择取返回。目前StorageFolder 尚不支持移动文件目录。通过StorageFolder 的部属,可以获取以下DateCreated/DisplayName/DisplayType/FolderRelativeId等等,以及下面的这些部属;

  • Name,目录名
  • Path,全路径
  • Attributes,文件系统相关属性
  • Properties,内容相关的部属
  • Provider,文件系统本身的一些属性(指本地文件系统或者OneDrive)

StorageFolder 既可以创建目录或者文件(文件和目录统称条目,即Item),又可以创建针对目录或者文件的查询,可以在获取条目的时候试用。StorageFolder 还可以针对自身进行操作,比如DeleteAsync可以删除自己;RenameAsync重命名自己。GetIndexedStateAsync 可以获取目录是否被包含在索引中。GetParentAsync获取上一级目录。IsEqual判断目录是否相同。IsOfType判断是否是目标类型(文件,目录或者其他)。TryGetChangeTracker返回一个StorageLibraryChangeTracker ,可以用于跟踪目录变动,似乎只适用于Doucments/Music/…这些预定义目录。

StorageFile 用于表示一个文件,其部属和StorageFolder 大致相同。支持IsAvailable部属,说明文件是否可以获取。有一些文件专属的操作,比如CopyAsync、CopyAndReplaceAsync。CreateStreamedFileAsync可以创建流式文件(为了避免写入文件的操作影响交互?)。GetFileFromApplicationUriAsync从应用按照目录(ms-appx?)加载文件。MoveAsync可以移动文件。RenameAsync重命名文件。OpenAsync/OpenReadAsync/OpenSequentialReadAsync/OpenTransactedWriteAsync以不同方式打开文件。ReplaceWithStreamedFileAsync覆盖文件内容。

对于接口方面,StorageFile和StorageFolder都实现了IStorageItem以及IStorageItem2。后者又实现了前者。

Windows.Storage.BulkAccess提供批量文件信息访问相关的操作。可以用来作为XAML Listview/GridView的Model。

Win32也为StorageFile和StorageFolder提供了COM接口,分别是:

上面两个COM接口可以用来处理底层文件系统的handle。

根据How can I get a Win32 HANDLE for a StorageFile or StorageFolder in UWP?帖子中Peter Torr - MSFT的答案举了一个例子,说明如何使用这个接口。

帖子同时提到WindowsStorageCOM.h中的定义在WINAPI_PARTITION_DESKTOP 的保护范围之内,不可以直接使用,需要把相关部分拷贝出来。

例子中使用的是WRL,如果是使用C++/WinRT的话,会更简单一点:

auto handle = winrt::file_handle{};
auto folder = ...; // 获取一个StorageFolder
auto unknown = folder.as<IUnknown>(); // 获取winrt::Windows::Foundation::IUnknown的com_ptr
auto handleAccessPtr = unknown.try_as<IStorageFolderHandleAccess>();
  hr = handleAccess->Create(filename, HANDLE_CREATION_OPTIONS::HCO_CREATE_ALWAYS,
    HANDLE_ACCESS_OPTIONS::HAO_WRITE | HANDLE_ACCESS_OPTIONS::HAO_READ,
    HANDLE_SHARING_OPTIONS::HSO_SHARE_NONE, HANDLE_OPTIONS::HO_NONE, nullptr,
    handle.put()); // 创建一个文件

其他

(完)

comments powered by Disqus