1# 文件路径使用指导 2 3Openharmony上用户数据统一由媒体库进行管理,用户数据用户数据可以通过mediaLibrary提供的接口能力进行访问和操作。 4 5> **说明:** 6> 7> 在进行功能开发前,请开发者查阅[媒体库开发概述](medialibrary-overview.md),了解如何获取媒体库实例和如何申请媒体库功能开发相关权限。 8 9为了保证应用的运行效率,大部分MediaLibrary调用都是异步的,对于异步调用的API均提供了callback和Promise两种方式,以下示例均采用Promise函数,更多方式可以查阅[API参考](../reference/apis/js-apis-medialibrary.md)。 10 11## 公共目录路径支持的文件格式 12 13在使用文件路径进行开发之前,需要了解各公共目录路径支持的文件格式说明。 14> **注意:** <br/> 15> 下表仅表示系统能识别的文件类型,在具体的开发中,开发者需要关注对应接口支持的文件格式。<br/> 如image编码功能只支持.jpeg和.webp,解码功能只支持.jpg .png .gif .bmp .webp RAW。 16 17| 目录路径 | 目录类型 | 媒体类型 | 说明 | 支持的文件格式 | 18| ---------- | ------------- | ------------- | -------------- | ------------------------------------------------------------ | 19| Camera/ | DIR_CAMERA | VIDEO amd IMAGE | 相机拍摄图片与录像的存放路径,目录与子目录下可以存放视频,图片类型文件。 | .bmp / .bm / .gif / .jpg /. jpeg / .jpe / .png / .webp / .raw / .svg / .heif / .mp4 / .3gp / .mpg / .mov / .webm / .mkv | 20| Videos/ | DIR_VIDEO | VIDEO | 视频专有目录,目录与子目录下只可以存放视频类型文件。| .mp4 / .3gp / .mpg / .mov / .webm / .mkv | 21| Pictures/ | DIR_IMAGE | IMAGE | 图片专有目录,目录与子目录下只可以存放图片类型文件。 | .bmp / .bm / .gif / .jpg /. jpeg / .jpe / .png / .webp / .raw / .svg / .heif | 22| Audios/ | DIR_AUDIO | AUDIO |音频专有目录,目录与子目录下只可以存放音频类型文件。| .aac/.mp3/.flac/.wav/.ogg | 23| Documents/ | DIR_DOCUMENTS | FILE |文档类型目录,目录与子目录下只可以存放音频,图片,视频以外类型文件。| - | 24| Download/ | DIR_DOWNLOAD | ALLTYPE |下载文件存放目录,目录与子目录下文件类型不受限制。| - | 25 26## 获取文件保存的公共目录 27 28不同类型的文件会保存到不同的公共目录下,可以通过接口[getPublicDirectory](../reference/apis/js-apis-medialibrary.md#getpublicdirectory8-1)来获取公共目录路径。 29 30**前提条件** 31 32- 获取媒体库mediaLibrary实例。 33- 申请媒体库读权限"ohos.permission.READ_MEDIA"。 34 35下面以获取Camera文件保存的公共目录为例。 36 37```ts 38async function example(){ 39 const context = getContext(this); 40 let media = mediaLibrary.getMediaLibrary(context); 41 let DIR_CAMERA = mediaLibrary.DirectoryType.DIR_CAMERA; 42 const dicResult = await media.getPublicDirectory(DIR_CAMERA); 43 if (dicResult == 'Camera/') { 44 console.info('mediaLibraryTest : getPublicDirectory passed'); 45 } else { 46 console.error('mediaLibraryTest : getPublicDirectory failed'); 47 } 48} 49``` 50 51## 沙箱与公共路径间文件的复制 52 53OpenHarmony提供应用沙箱机制,增加目录可见性数据访问防线,减少了应用数据和用户隐私信息泄露,建立了更加严格安全的应用沙盒隔离能力。 54 55放在公共路径下的文件,用户可以通过系统应用“文件管理”、“图库”访问,但应用沙箱内的文件,只有应用本身可以访问。 56 57### 复制文件 58 59通过接口[mediaLibrary.FileAsset.open](../reference/apis/js-apis-medialibrary.md#open8-1)可以打开公共路径文件。 60 61通过接口[fs.open](../reference/apis/js-apis-file-fs.md#fsopen)可以打开沙箱路径文件,沙箱路径必须通过应用上下文context进行访问。 62 63**前提条件** 64 65- 获取媒体库mediaLibrary实例。 66- 申请媒体库读写权限"ohos.permission.READ_MEDIA, ohos.permission.WRITE_MEDIA"。 67- 除了@ohos.multimedia.mediaLibrary外,还需要导入模块[@ohos.file.fs](../reference/apis/js-apis-file-fs.md)。 68- 测试文件 "testFile.txt" 已创建且有文件内容。 69 70**开发步骤** 71 721. 调用[context.filesDir](../reference/apis/js-apis-file-fs.md)获取应用沙箱路径。 732. 调用MediaLibrary.getFileAssets和FetchFileResult.getFirstObject获取公共目录中的FileAsset实例。 743. 调用fs.open打开沙箱路径文件。 754. 调用fileAsset.open打开公共路径文件。 765. 调用[fs.copyfile](../reference/apis/js-apis-file-fs.md#fscopyfile)复制文件。 776. 调用fileAsset.close和[fs.close](../reference/apis/js-apis-file-fs.md#fsclose)关闭文件。 78 79**示例1 将公共路径文件复制到沙箱路径下** 80 81```ts 82async function copyPublic2Sandbox() { 83 try { 84 const context = getContext(this); 85 let media = mediaLibrary.getMediaLibrary(context); 86 let sandboxDirPath = context.filesDir; 87 let fileKeyObj = mediaLibrary.FileKey; 88 let fileAssetFetchOp = { 89 selections: fileKeyObj.DISPLAY_NAME + '= ?', 90 selectionArgs: ['testFile.txt'], 91 }; 92 let fetchResult = await media.getFileAssets(fileAssetFetchOp); 93 let fileAsset = await fetchResult.getFirstObject(); 94 95 let fdPub = await fileAsset.open('rw'); 96 let fdSand = await fs.open(sandboxDirPath + '/testFile.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); 97 await fs.copyFile(fdPub, fdSand.fd); 98 99 await fileAsset.close(fdPub); 100 await fs.close(fdSand.fd); 101 102 let content_sand = await fs.readText(sandboxDirPath + '/testFile.txt'); 103 console.info('content read from sandbox file: ', content_sand) 104 } catch (err) { 105 console.info('[demo] copyPublic2Sandbox fail, err: ', err); 106 } 107} 108``` 109 110**示例2 将应用沙箱路径文件复制到公共路径** 111 112```ts 113async function copySandbox2Public() { 114 const context = getContext(this); 115 let media = mediaLibrary.getMediaLibrary(context); 116 let sandboxDirPath = context.filesDir; 117 118 let DIR_DOCUMENTS = mediaLibrary.DirectoryType.DIR_DOCUMENTS; 119 const publicDirPath = await media.getPublicDirectory(DIR_DOCUMENTS); 120 try { 121 let fileAsset = await media.createAsset(mediaLibrary.MediaType.FILE, 'testFile02.txt', publicDirPath); 122 console.info('createFile successfully, message = ' + fileAsset); 123 } catch (err) { 124 console.error('createFile failed, message = ' + err); 125 } 126 try { 127 let fileKeyObj = mediaLibrary.FileKey; 128 let fileAssetFetchOp = { 129 selections: fileKeyObj.DISPLAY_NAME + '= ?', 130 selectionArgs: ['testFile02.txt'], 131 }; 132 let fetchResult = await media.getFileAssets(fileAssetFetchOp); 133 var fileAsset = await fetchResult.getFirstObject(); 134 } catch (err) { 135 console.error('file asset get failed, message = ' + err); 136 } 137 let fdPub = await fileAsset.open('rw'); 138 let fdSand = await fs.open(sandboxDirPath + 'testFile.txt', fs.OpenMode.READ_WRITE); 139 await fs.copyFile(fdSand.fd, fdPub); 140 await fileAsset.close(fdPub); 141 await fs.close(fdSand.fd); 142 let fdPubRead = await fileAsset.open('rw'); 143 try { 144 let arrayBuffer = new ArrayBuffer(4096); 145 await fs.read(fdPubRead, arrayBuffer); 146 var content_pub = String.fromCharCode(...new Uint8Array(arrayBuffer)); 147 fileAsset.close(fdPubRead); 148 } catch (err) { 149 console.error('read text failed, message = ', err); 150 } 151 console.info('content read from public file: ', content_pub); 152} 153``` 154 155### 读写文件内容 156 157通过[mediaLibrary](../reference/apis/js-apis-medialibrary.md)的接口FileAsset.open和FileAsset.close可以打开和关闭文件。通过[file.fs](../reference/apis/js-apis-file-fs.md)中的接口fs.read和fs.write可以读写文件。 158 159**前提条件** 160 161- 获取媒体库mediaLibrary实例。 162- 申请媒体库读写权限"ohos.permission.READ_MEDIA, ohos.permission.WRITE_MEDIA"。 163- 除了@ohos.multimedia.mediaLibrary外,还需要导入模块[@ohos.file.fs](../reference/apis/js-apis-file-fs.md)。 164 165**开发步骤** 166 1671. 创建用于读写示例的文件。 168 169```ts 170async function example() { 171 let mediaType = mediaLibrary.MediaType.FILE; 172 let DIR_DOCUMENTS = mediaLibrary.DirectoryType.DIR_DOCUMENTS; 173 const context = getContext(this); 174 let media = mediaLibrary.getMediaLibrary(context); 175 const path = await media.getPublicDirectory(DIR_DOCUMENTS); 176 media.createAsset(mediaType, "testFile.txt", path).then((asset) => { 177 console.info("createAsset successfully:" + JSON.stringify(asset)); 178 }).catch((err) => { 179 console.error("createAsset failed with error: " + err); 180 }); 181} 182``` 183 1842. 使用open打开文件。 185 1863. 使用[fs.write](../reference/apis/js-apis-file-fs.md#fswrite)写入文件,以string形式传入写入数据。 187 1884. 使用[fs.read](../reference/apis/js-apis-file-fs.md#fsread)读取文件,以 ArrayBuffer 形式保存读取结果。 189 1905. 将ArrayBuffer转化为string,以string形式得到文件内容。 191 1926. 使用close关闭文件。 193 194**示例1 打开现有文件、向文件中写入** 195 196```ts 197async function writeOnlyPromise() { 198 const context = getContext(this); 199 let media = mediaLibrary.getMediaLibrary(context); 200 let fileKeyObj = mediaLibrary.FileKey; 201 let fileAssetFetchOp = { 202 selections: fileKeyObj.DISPLAY_NAME + '= ?', 203 selectionArgs: ['testFile.txt'], 204 }; 205 let fetchResult = await media.getFileAssets(fileAssetFetchOp); 206 let fileAsset = await fetchResult.getFirstObject(); 207 console.info('fileAssetName: ', fileAsset.displayName); 208 209 try { 210 let fd = await fileAsset.open('w'); 211 console.info('file descriptor: ', fd); 212 await fs.write(fd, "Write file test content."); 213 await fileAsset.close(fd); 214 } catch (err) { 215 console.error('write file failed, message = ', err); 216 } 217} 218``` 219 220**示例2 打开现有文件,读取文件内容** 221 222```ts 223async function readOnlyPromise() { 224 const context = getContext(this); 225 let media = mediaLibrary.getMediaLibrary(context); 226 let fileKeyObj = mediaLibrary.FileKey; 227 let fileAssetFetchOp = { 228 selections: fileKeyObj.DISPLAY_NAME + '= ?' , 229 selectionArgs: ['testFile.txt'], 230 }; 231 let fetchResult = await media.getFileAssets(fileAssetFetchOp); 232 let fileAsset = await fetchResult.getFirstObject(); 233 console.info('fileAssetName: ', fileAsset.displayName); 234 235 try { 236 let fd = await fileAsset.open('r'); 237 let arrayBuffer = new ArrayBuffer(4096); 238 await fs.read(fd, arrayBuffer); 239 let fileContent = String.fromCharCode(...new Uint8Array(arrayBuffer)); 240 globalThis.fileContent = fileContent; 241 globalThis.fileName = fileAsset.displayName; 242 console.info('file content: ', fileContent); 243 await fileAsset.close(fd); 244 } catch (err) { 245 console.error('read file failed, message = ', err); 246 } 247} 248``` 249 250