• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 用户文件uri介绍
2
3用户文件uri是文件的唯一标识,在对用户文件进行访问与修改等操作时往往都会使用到uri,不建议开发者解析uri中的片段用于业务代码开发,不同类型的uri使用方式将在下文详细介绍。
4
5## uri的类型
6
7uri类型可以归纳为文档类uri和媒体文件uri两类
8
9- 文档类uri:由picker拉起文件管理器选择或保存返回,以及通过fileAccess模块获取。具体获取方式参见[文档类uri获取方式](#文档类uri获取方式)。
10- 媒体文件uri:由picker通过拉起图库选择图片或者视频返回,通过photoAccessHelper模块获取图片或者视频文件的uri,以及通过userFileManager模块获取图片、视频或者音频文件的uri。具体获取方式参见[媒体文件uri获取方式](#媒体文件uri获取方式)。
11
12![user-file-uri-intro](figures/user-file-uri-intro.png)
13
14## 文档类uri
15
16### 文档类uri介绍
17
18**文档类uri的格式类型为:**
19
20'file://docs/storage/Users/currentUser/\<relative_path\>/test.txt'
21
22**其中各个字段表示的含义为:**
23
24| uri字段          | 说明        |
25| ------------- | ------------------- |
26| 'file://docs/storage/Users/currentUser/' | 文件管理器的根目录。|
27| '\<relative_path\>/' | 文件在根目录下的相对路径。例如:'Download/'和'Documents/'。|
28| 'test.txt' | 用户文件系统中存储的文件名,支持的文件类型为文件管理器支持的所有类型,以文件管理器为准,例如txt、jpg、mp4和mp3等格式的文件。|
29
30### 文档类uri获取方式
31
321. 通过[DocumentViewPicker接口](../reference/apis-core-file-kit/js-apis-file-picker.md#documentviewpicker)选择或保存文件,返回选择或保存的文件uri。
33
342. 通过[AudioViewPicker接口](../reference/apis-core-file-kit/js-apis-file-picker.md#audioviewpicker)选择或保存文件,返回选择或保存的文件uri。
35
363. 通过[PhotoViewPicker.save接口](../reference/apis-core-file-kit/js-apis-file-picker.md#save)保存文件,返回保存的文件uri。
37
384. 通过[fileAccess模块](../reference/apis-core-file-kit/js-apis-fileAccess-sys.md)获取文档类目录下的文件得到对应文件的[FileInfo](../reference/apis-core-file-kit/js-apis-fileAccess-sys.md#fileinfo)对象,此对象中就包含对应文件或者目录的uri属性,此模块中的接口为系统接口,使用此模块需要注意应用是否为系统应用。支持获取文件uri的目录有:
39   - 外部存储目录
40   - Docs目录
41   - Download目录
42   - Desktop目录
43   - Documents目录
44   - Share共享盘目录
45
46### 文档类uri的使用方式
47
48normal等级的应用使用此类uri的方式只能通过[fs模块](../reference/apis-core-file-kit/js-apis-file-fs.md)进行进一步处理,其他模块使用此uri是会报没有权限的错误。示例代码参见picker中的[选择文档类文件](./select-user-file.md#选择文档类文件)和[保存文档类文件](./save-user-file.md#保存文档类文件)。
49
50system_basic等级及以上的应用使用此类uri的方式除了上述通过fs模块外还可以通过[fileAccess模块](../reference/apis-core-file-kit/js-apis-fileAccess-sys.md)进行进一步处理,使用此模块需要在配置文件module.json5中声明ohos.permission.FILE_ACCESS_MANAGERohos.permission.GET_BUNDLE_INFO_PRIVILEGED 权限,此权限为system_basic权限,仅供系统应用使用。其他模块使用此uri会报没有权限的错误。下面示例为使用fileAccess模块创建文件得到uri后对其进行重命名操作:
51
521. 通过[fileAccess模块](../reference/apis-core-file-kit/js-apis-fileAccess-sys.md)获取文件uri。
532. 使用获取到的文件uri进行重命名操作。
54
55```ts
56import { BusinessError } from '@ohos.base';
57import Want from '@ohos.app.ability.Want';
58import common from '@ohos.app.ability.common';
59import fileAccess from '@ohos.file.fileAccess';
60// context 是EntryAbility 传过来的context
61let context = getContext(this) as common.UIAbilityContext;
62
63async function example() {
64    let fileAccessHelper: fileAccess.FileAccessHelper;
65    // wantInfos 从getFileAccessAbilityInfo()获取
66    let wantInfos: Array<Want> = [
67      {
68        bundleName: "com.ohos.UserFile.ExternalFileManager",
69        abilityName: "FileExtensionAbility",
70      },
71    ]
72    try {
73      fileAccessHelper = fileAccess.createFileAccessHelper(context, wantInfos);
74      if (!fileAccessHelper) {
75        console.error("createFileAccessHelper interface returns an undefined object");
76      }
77      // 以内置存储目录为例
78      // 示例代码sourceUri表示Download目录,该uri是对应的fileInfo中uri
79      // 开发者应根据自己实际获取的uri进行开发
80      let sourceUri: string = "file://docs/storage/Users/currentUser/Download";
81      let displayName: string = "file1.txt";
82      let fileUri: string;
83      try {
84        // 创建文件返回该文件的uri
85        fileUri = await fileAccessHelper.createFile(sourceUri, displayName);
86        if (!fileUri) {
87          console.error("createFile return undefined object");
88        }
89        console.log("createFile success, fileUri: " + JSON.stringify(fileUri));
90        // 将刚创建的文件进行重命名,返回新文件的uri
91        let renameUri = await fileAccessHelper.rename(fileUri, "renameFile.txt");
92        console.log("rename success, renameUri: " + JSON.stringify(renameUri));
93      } catch (err) {
94        let error: BusinessError = err as BusinessError;
95        console.error("createFile failed, errCode:" + error.code + ", errMessage:" + error.message);
96      }
97    } catch (err) {
98      let error: BusinessError = err as BusinessError;
99      console.error("createFileAccessHelper failed, errCode:" + error.code + ", errMessage:" + error.message);
100    }
101  }
102```
103
104## 媒体文件uri
105
106### 媒体文件uri介绍
107
108**媒体文件uri的格式类型为:**
109
110图片uri格式:
111
112- 'file://media/Photo/\<id\>/IMG_datetime_0001/displayName.jpg'
113
114视频uri格式:
115
116- 'file://media/Photo/\<id>/VID_datetime_0001/displayName.mp4'
117
118音频uri格式:
119
120- 'file://media/Audio/\<id>/AUD_datetime_0001/displayName.mp3'
121
122**其中各个字段表示的含义为:**
123
124| uri字段          | 说明        |
125| ------------- | ------------------- |
126| 'file://media' | 表示这个uri是媒体文件。 |
127| 'Photo' | Photo表示这个uri是媒体文件中的图片或者视频类文件。 |
128| 'Audio' | 表示这个uri是媒体文件中的音频类文件。 |
129| '\<id>' | 表示在数据库中多个表中处理后的值,并不是指表中的file_id列,注意请不要使用此id去数据库中查询具体文件。 |
130| 'IMG_datetime_0001' | 表示图片文件在用户文件系统中存储的文件名去掉后缀剩下的部分。 |
131| 'VID_datetime_0001' | 表示视频文件在用户文件系统中存储的文件名去掉后缀剩下的部分。 |
132| 'AUD_datetime_0001' | 表示音频文件在用户文件系统中存储的文件名去掉后缀剩下的部分。 |
133| 'displayName.jpg' | 表示图片文件对外展示的displayName,使用[userFileManager.commitModify](../reference/apis-core-file-kit/js-apis-userFileManager-sys.md#commitmodify)接口重命名修改的就是这个值,需要注意这个值修改后uri也会发生改变。 |
134| 'displayName.mp4' | 表示视频文件对外展示的displayName,使用[userFileManager.commitModify](../reference/apis-core-file-kit/js-apis-userFileManager-sys.md#commitmodify)接口重命名修改的就是这个值,需要注意这个值修改后uri也会发生改变。 |
135| 'displayName.mp3' | 表示音频文件对外展示的displayName,使用[userFileManager.commitModify](../reference/apis-core-file-kit/js-apis-userFileManager-sys.md#commitmodify)接口重命名修改的就是这个值,需要注意这个值修改后uri也会发生改变。 |
136
137### 媒体文件uri获取方式
138
1391. 通过[PhotoViewPicker.select接口](../reference/apis-core-file-kit/js-apis-file-picker.md#select)选择媒体文件,返回选择的媒体文件文件的uri。
140
1412. 通过[photoAccessHelper模块](../reference/apis-media-library-kit/js-apis-photoAccessHelper.md)中的[getAssets](../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#getassets)或[createAsset](../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#createasset)接口获取媒体文件对应文件的uri。
142
1433. 通过[userFileManager模块](../reference/apis-core-file-kit/js-apis-userFileManager-sys.md)中的[getPhotoAssets](../reference/apis-core-file-kit/js-apis-userFileManager-sys.md#getphotoassets)、[getAudioAssets](../reference/apis-core-file-kit/js-apis-userFileManager-sys.md#getaudioassets)、[createAudioAsset](../reference/apis-core-file-kit/js-apis-userFileManager-sys.md#createaudioasset10)或[createPhotoAsset](../reference/apis-core-file-kit/js-apis-userFileManager-sys.md#createphotoasset)接口获取媒体文件对应文件的uri。
144
145### 媒体文件uri的使用方式
146
147normal等级的应用使用此类uri可以通过[photoAccessHelper模块](../reference/apis-media-library-kit/js-apis-photoAccessHelper.md)进行进一步处理。示例代码参见媒体资源使用指导中的[指定URI获取图片或视频资源](../media/medialibrary/photoAccessHelper-resource-guidelines.md#指定uri获取图片或视频资源)。此接口需要申请相册管理模块读权限'ohos.permission.READ_IMAGEVIDEO',在使用中需要注意应用是否有此权限。
148
149system_basic等级及以上的应用使用此类uri的方式除了上述通过photoAccessHelper模块外还可以通过[userFileManager模块](../reference/apis-core-file-kit/js-apis-userFileManager-sys.md)进行进一步处理,接口详细使用方式见接口文档。
150
151若normal等级的应用不想申请权限也可以通过临时授权的方式使用[PhotoViewPicker.select接口](../reference/apis-core-file-kit/js-apis-file-picker.md#select)得到的uri使用[photoAccessHelper.getAssets接口](../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#getassets)获取对应uri的PhotoAsset对象。这种方式获取的对象可以调用[getThumbnail](../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#getthumbnail)获取缩略图和使用[get接口](../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#get)读取[PhotoKeys](../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#photokeys)中的部分信息。
152
153以下为PhotoKeys中支持临时授权方式可以读取的信息:
154
155| 名称          | 值              | 说明                                                       |
156| ------------- | ------------------- | ---------------------------------------------------------- |
157| URI           | 'uri'                 | 文件uri。                                                   |
158| PHOTO_TYPE    | 'media_type'           | 媒体文件类型。                                              |
159| DISPLAY_NAME  | 'display_name'        | 显示名字。                                                   |
160| SIZE          | 'size'                | 文件大小。                                                   |
161| DATE_ADDED    | 'date_added'          | 添加日期(添加文件时间距1970年1月1日的秒数值)。             |
162| DATE_MODIFIED | 'date_modified'       | 修改日期(修改文件时间距1970年1月1日的秒数值,修改文件名不会改变此值,当文件内容发生修改时才会更新)。 |
163| DURATION      | 'duration'            | 持续时间(单位:毫秒)。                                    |
164| WIDTH         | 'width'               | 图片宽度(单位:像素)。                                    |
165| HEIGHT        | 'height'              | 图片高度(单位:像素)。                                      |
166| DATE_TAKEN    | 'date_taken'          | 拍摄日期(文件拍照时间距1970年1月1日的秒数值)。                |
167| ORIENTATION   | 'orientation'         | 图片文件的方向。                                             |
168| TITLE         | 'title'               | 文件标题。                                                   |
169
170下面为通过临时授权方式使用媒体文件uri进行获取缩略图和读取文件部分信息的示例代码:
171
172```ts
173import picker from '@ohos.file.picker';
174import photoAccessHelper from '@ohos.file.photoAccessHelper';
175import { BusinessError } from '@ohos.base';
176import dataSharePredicates from '@ohos.data.dataSharePredicates';
177
178// 定义一个uri数组,用于接收PhotoViewPicker选择图片返回的uri
179let uris: Array<string> = [];
180const context = getContext(this);
181
182// 调用PhotoViewPicker.select选择图片
183async function photoPickerGetUri() {
184  try {
185    let PhotoSelectOptions = new picker.PhotoSelectOptions();
186    PhotoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;
187    PhotoSelectOptions.maxSelectNumber = 1;
188    let photoPicker = new picker.PhotoViewPicker();
189    photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult: picker.PhotoSelectResult) => {
190      console.info('PhotoViewPicker.select successfully, PhotoSelectResult uri: ' + JSON.stringify(PhotoSelectResult));
191      uris = PhotoSelectResult.photoUris;
192    }).catch((err: BusinessError) => {
193      console.error('PhotoViewPicker.select failed with err: ' + JSON.stringify(err));
194    });
195  } catch (error) {
196    let err: BusinessError = error as BusinessError;
197    console.error('PhotoViewPicker failed with err: ' + JSON.stringify(err));
198  }
199}
200
201async function uriGetAssets() {
202try {
203    let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
204    let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
205    // 配置查询条件,使用PhotoViewPicker选择图片返回的uri进行查询
206    predicates.equalTo('uri', uris[0]);
207    let fetchOption: photoAccessHelper.FetchOptions = {
208      fetchColumns: [],
209      predicates: predicates
210    };
211    let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await phAccessHelper.getAssets(fetchOption);
212    // 得到uri对应的PhotoAsset对象,读取文件的部分信息
213    const asset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject();
214    console.info('asset displayName: ', asset.displayName);
215    console.info('asset uri: ', asset.uri);
216    console.info('asset photoType: ', asset.photoType);
217    console.info('asset width: ', asset.get(photoAccessHelper.PhotoKeys.WIDTH));
218    console.info('asset height: ', asset.get(photoAccessHelper.PhotoKeys.HEIGHT));
219    console.info('asset title: ' + asset.get(photoAccessHelper.PhotoKeys.TITLE));
220    // 获取缩略图
221    asset.getThumbnail((err, pixelMap) => {
222      if (err == undefined) {
223        console.info('getThumbnail successful ' + JSON.stringify(pixelMap));
224      } else {
225        console.error('getThumbnail fail', err);
226      }
227    });
228  } catch (error){
229    console.error('uriGetAssets failed with err: ' + JSON.stringify(error));
230  }
231}
232```
233## 通过uri复制文件
234
235用户复制文件到指定目录
236
2371. 通过[createFileAccessHelper](../reference/apis-core-file-kit/js-apis-fileAccess-sys.md#fileaccesscreatefileaccesshelper)创建fileAccessHelper helper。
238
2392. 获取源文件的srcUri。
240
2413. 获取目的路径的destUri。
242
2434. 获取备用名 fileName。
244
2455. 使用helper.[copyFile](../reference/apis-core-file-kit/js-apis-fileAccess-sys.md#copyfile11)(srcUri, destUri, fileName) 进行文件操作。
246
247复制文件代码示例:
248
249```
250import { BusinessError } from '@ohos.base';
251import Want from '@ohos.app.ability.Want';
252import common from '@ohos.app.ability.common';
253import fileAccess from '@ohos.file.fileAccess';
254
255async example() {
256    let fileAccessHelper: fileAccess.FileAccessHelper;
257    // wantInfos 从getFileAccessAbilityInfo()获取
258    let wantInfos: Array<Want> = [
259      {
260        bundleName: "com.ohos.UserFile.ExternalFileManager",
261        abilityName: "FileExtensionAbility",
262      },
263    ]
264    try {
265      // context 是EntryAbility 传过来的context
266      let context = getContext(this) as common.UIAbilityContext;
267      fileAccessHelper = fileAccess.createFileAccessHelper(context, wantInfos);
268      if (!fileAccessHelper) {
269        console.error("createFileAccessHelper interface returns an undefined object");
270      }
271      // 以内置存储目录为例
272      // 示例代码sourceUri表示Download目录,该uri是对应的fileInfo中uri
273      // 开发者应根据自己实际获取的uri进行开发
274      let sourceUri: string = "file://docs/storage/Users/currentUser/Download/one.txt";
275      // 将文件复制到的位置uri
276      let destUri: string = "file://docs/storage/Users/currentUser/Documents";
277      // 如果文件名冲突,要使用的文件名
278      let displayName: string = "file1.txt";
279      // 存放返回的uri
280      let fileUri: string;
281      try {
282        // 复制文件返回该文件的uri
283        fileUri = await fileAccessHelper.copyFile(sourceUri, destUri, displayName);
284        if (!fileUri) {
285          console.error("copyFile return undefined object");
286        }
287        console.log("copyFile success, fileUri: " + JSON.stringify(fileUri));
288      } catch (err) {
289        let error: BusinessError = err as BusinessError;
290        console.error("copyFile failed, errCode:" + error.code + ", errMessage:" + error.message);
291      }
292    } catch (err) {
293      let error: BusinessError = err as BusinessError;
294      console.error("createFileAccessHelper failed, errCode:" + error.code + ", errMessage:" + error.message);
295    }
296  }
297```
298