# 选择用户文件

用户需要分享文件、保存图片、视频等用户文件时，开发者可以通过系统预置的[选择器](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-picker)，实现该能力。通过Picker访问相关文件，将拉起对应的应用，引导用户完成界面操作，接口本身无需申请权限。Picker选择文件或文件夹获取到的URI只具有临时读写权限，获取持久化权限需要通过[FilePicker设置永久授权](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/file-persistpermission#通过picker获取临时授权并进行授权持久化)方式获取。

约束限制

如果使用系统能力为SystemCapability.FileManagement.UserFileService.FolderSelection的接口时，可使用[canIUse](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-syscap#caniuse)接口，确认设备是否具有该系统能力：

```
if (!canIUse('SystemCapability.FileManagement.UserFileService.FolderSelection')) {
      console.error('This API is not supported on this device');
      return;
}
```

根据用户文件的常见类型，选择器（FilePicker）分别提供以下选项：

* [PhotoViewPicker](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-picker#photoviewpickerdeprecated)：适用于图片或视频类型文件的选择与保存（该接口在后续版本不再演进）。请使用PhotoAccessHelper的[PhotoViewPicker](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-photoaccesshelper-photoviewpicker)来选择图片文件。请使用[安全控件保存媒体库资源](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/photoaccesshelper-savebutton)。

* [DocumentViewPicker](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-picker#documentviewpicker)：适用于文件类型文件的选择与保存。DocumentViewPicker对接的选择资源来自于FilePicker，负责文件类型的资源管理，文件类型不区分后缀，比如浏览器下载的图片、文档等，都属于文件类型。

* [AudioViewPicker](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-picker#audioviewpicker)：适用于音频类型文件的选择与保存。AudioViewPicker目前对接的选择资源来自于AudioPicker。

#### 选择图片或视频类文件

[PhotoViewPicker](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-picker#photoviewpickerdeprecated)在后续版本不再演进，请使用PhotoAccessHelper的[PhotoViewPicker](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-photoaccesshelper-photoviewpicker)来选择图片文件。  

#### 选择文档类文件

1. 导入选择器模块和文件管理模块。

   ```
   import  { picker } from '@kit.CoreFileKit';
   import { fileIo } from '@kit.CoreFileKit';
   import { common } from '@kit.AbilityKit';
   import { BusinessError } from '@kit.BasicServicesKit';
   ```

2. 需根据实际业务需求配置[文档选择选项](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-picker#documentselectoptions)。以下代码仅例举各选项的配置参考。

   ```
   const documentSelectOptions = new picker.DocumentSelectOptions();
   // 选择文件最大个数（可选）。API version 20及之前的版本，单次文件选择的最大数量上限为500个，默认值也为500。目录选择功能仅对具备该系统能力的设备开放，且单次最多可选择1个目录。API version 21及之后的版本取消文件选择数量的限制。受系统能力限制，选择文件数量过大可能会出现功能异常或处理性能较差等情况，建议单次选择文件个数不超过1万个。API version 23及之后的版本取消目录选择数量的限制。
   documentSelectOptions.maxSelectNumber = 5;
   // 指定选择的文件或者目录的URI（可选）。
   documentSelectOptions.defaultFilePathUri = "file://docs/storage/Users/currentUser/test";
   // 选择的文档类型，默认值是FILE(文件类型)。从API版本26.0.0开始，当文件类型是FOLDER时，Phone设备支持该参数；当文件类型是MIXED时，该参数在2in1设备中可正常使用，在其他设备中无效果。
   documentSelectOptions.selectMode = picker.DocumentSelectMode.FILE;
   // 选择文件的后缀类型['后缀类型描述|后缀类型']（可选，不传该参数，默认不过滤，即显示所有文件），若选择项存在多个后缀名，则每一个后缀名之间用英文逗号进行分隔（可选），后缀类型名不能超过100。此外2in1设备支持通配符方式['所有文件(*.*)|.*']（说明：从API version 17开始，手机支持该配置），表示为显示所有文件。
    documentSelectOptions.fileSuffixFilters = ['图片(.png, .jpg)|.png,.jpg', '文档|.txt', '视频|.mp4', '.pdf'];
   // 选择是否对指定文件或目录授权，true为授权，当为true时，defaultFilePathUri为必选参数，拉起文管授权界面；false为非授权(默认为false)，拉起常规文管界面（可选）。该参数在2in1设备中可正常使用，在其他设备中无效果。
   documentSelectOptions.authMode = false;
   // 批量授权模式，默认为false（非批量授权模式）。当multiAuthMode为true时为批量授权模式。当multiAuthMode为true时，只有multiUriArray参数生效，其他参数不生效。该参数在Phone设备中可正常使用，在其他设备中无效果。
   documentSelectOptions.multiAuthMode = false;
   // 需要传入批量授权的uri数组（仅支持文件，文件夹不生效）。配合multiAuthMode使用。当multiAuthMode为false时，配置该参数不生效。该参数在Phone设备中可正常使用，在其他设备中无效果。
   documentSelectOptions.multiUriArray = ["file://docs/storage/Users/currentUser/test", "file://docs/storage/Users/currentUser/2test"];
   // 开启聚合视图模式，支持拉起文件管理应用的聚合视图。默认为DEFAULT，表示该参数不生效，非聚合视图。当该参数置为非DEFAULT时，其他参数不生效。API版本26.0.0及之后的版本当该参数置为非DEFAULT时，仅fileSuffixFilters参数生效，其他参数不生效。
   // 该参数在Phone设备中可正常使用，在其他设备中无效果。
   documentSelectOptions.mergeMode = picker.MergeTypeMode.DEFAULT;
   // 是否支持加密（仅支持文件，文件夹不生效），默认为false。该参数为true时，在Picker界面可以选择对文件进行加密。（说明：从API version 19开始支持该参数）。
   documentSelectOptions.isEncryptionSupported = false;
   // 是否支持多选文件夹。默认为false，表示不支持多选文件夹，需要与selectMode参数配合使用。（说明：从API版本26.0.0开始支持该参数）。
   documentSelectOptions.allowsMulFolderSelection = false;
   ```

3. 创建文件选择器[DocumentViewPicker](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-picker#documentviewpicker)实例。调用[select()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-picker#select-3)接口拉起FilePicker应用界面进行文件选择。

   ```
   let uris: string[] = [];
   let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
   const documentViewPicker = new picker.DocumentViewPicker(context);
   documentViewPicker.select(documentSelectOptions).then((documentSelectResult: string[]) => {
     uris = documentSelectResult;
     console.info('documentViewPicker.select to file succeed and uris are:' + uris);
     // ...
   }).catch((err: BusinessError) => {
     console.error(`Invoke documentViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
   });
   ```

   ![](https://media:301785151677300859)  
   1. 使用Picker获取的[select()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-picker#select-3)返回的URI权限是临时读写权限，待退出应用后台后，获取的临时权限就会失效。

   2. 如果想要获取持久化权限，请参考[文件持久化授权访问](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/file-persistpermission#通过picker获取临时授权并进行授权持久化)。

   3. 开发者可以根据结果集中URI做进一步的处理。建议定义一个全局变量保存URI。

   4. 如有获取元数据需求，可以通过[文件管理](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-fs)和[文件URI](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-fileuri)根据URI获取部分文件属性信息，比如文件大小、访问时间、修改时间、文件名、文件路径等。
4. 待界面从FilePicker返回后，使用[fileIo.openSync](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-fs#fileioopensync)接口通过URI打开这个文件得到文件描述符（fd）。

   ```
   if (uris.length > 0) {
     let uri: string = uris[0];
     // 这里需要注意接口权限参数是fileIo.OpenMode.READ_ONLY。
     let file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY);
     console.info('file fd: ' + file.fd);
   }
   ```

5. 通过fd使用[fileIo.readSync](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-fs#fileioreadsync)接口读取这个文件内的数据。

   ```
   let buffer = new ArrayBuffer(4096);
   let readLen = fileIo.readSync(file.fd, buffer);
   console.info('readSync data to file succeed and buffer size is:' + readLen);
   // 读取完成后关闭fd。
   fileIo.closeSync(file);
   ```

#### 选择音频类文件

1. 导入选择器模块和文件管理模块。

   ```
   import  { picker } from '@kit.CoreFileKit';
   import { fileIo } from '@kit.CoreFileKit';
   import { BusinessError } from '@kit.BasicServicesKit';
   import { common } from '@kit.AbilityKit';
   ```

2. 创建音频类型文件选择选项实例。

   ![](https://media:301785151677339861)  
   目前AudioSelectOptions不支持参数配置，默认可以选择所有类型的用户文件。

   ```
   const audioSelectOptions = new picker.AudioSelectOptions();
   ```

3. 创建音频选择器[AudioViewPicker](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-picker#audioviewpicker)实例。调用[select()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-picker#select-5)接口拉起AudioPicker应用界面进行文件选择。

   ```
   let uris: string[] = [];
   // 请在组件内获取context，确保this.getUIContext().getHostContext()返回结果为UIAbilityContext
   let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
   const audioViewPicker = new picker.AudioViewPicker(context);
   audioViewPicker.select(audioSelectOptions).then((audioSelectResult: Array<string>) => {
     // 文件选择成功后，返回被选中音频的URI结果集。
     uris = audioSelectResult;
     console.info('audioViewPicker.select to file succeed and uri is:' + uris);
     // ...
   }).catch((err: BusinessError) => {
     console.error(`Invoke audioViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
   })
   ```

   ![](https://media:301785151677376862)  
   1. 使用Picker获取的[select()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-picker#select-3)返回的URI权限是临时只读权限，待退出应用后台后，获取的临时权限就会失效。

   2. 如果想要获取持久化权限，请参考[文件持久化授权访问](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/file-persistpermission#通过picker获取临时授权并进行授权持久化)。

   3. 开发者可以根据结果集中的URI做读取文件数据操作。建议定义一个全局变量保存URI。例如通过[文件管理](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-fs)模块的接口根据URI拿到音频资源的文件描述符（fd），再配合媒体服务实现音频播放的开发，具体请参考[音频播放开发指导](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/audio-playback-overview)。
4. 待界面从AudioPicker返回后，可以使用[fileIo.openSync](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-fs#fileioopensync)接口通过URI打开这个文件得到文件描述符（fd）。

   ```
   if (uris.length > 0) {
      let uri: string = uris[0];
      // 这里需要注意接口权限参数是fileIo.OpenMode.READ_ONLY。
      let file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY);
      console.info('file fd: ' + file.fd);
   }
   ```

5. 通过fd可以使用[fileIo.readSync](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-fs#readsync)接口读取这个文件内的数据。

   ```
   let buffer = new ArrayBuffer(4096);
   let readLen = fileIo.readSync(file.fd, buffer);
   console.info('readSync data to file succeed and buffer size is:' + readLen);
   // 读取完成后关闭fd。
   fileIo.closeSync(file);
   ```

#### 示例代码

* [选择并查看文档与媒体文件](https://gitcode.com/HarmonyOS_Samples/picker)  
