1# 保存用户文件 2<!--Kit: Core File Kit--> 3<!--Subsystem: FileManagement--> 4<!--Owner: @wang_zhangjun; @zhuangzhuang--> 5<!--Designer: @wang_zhangjun; @zhuangzhuang; @renguang1116--> 6<!--Tester: @liuhonggang123; @yue-ye2; @juxiaopang--> 7<!--Adviser: @foryourself--> 8 9在从网络下载文件到本地或将已有用户文件另存为新的文件路径等场景下,需要使用FilePicker提供的保存用户文件的能力。需关注以下关键点: 10 11**权限说明** 12 13- 通过Picker获取的URI默认只具备**临时读写权限**,临时授权在应用退出后台自动失效。 14- 获取持久化权限需要通过[FilePicker设置永久授权](file-persistPermission.md#通过picker获取临时授权并进行授权持久化)方式获取。 15- 使用Picker对音频、图片、视频、文档类文件的保存操作**无需申请权限**。 16 17**系统隔离说明** 18 19- 通过Picker保存的文件存储在用户指定的目录。此类文件与图库管理的资源隔离,无法在图库中看到。 20- 若开发者需要保存图片、视频资源到图库,可使用用户无感的[安全控件进行保存](../media/medialibrary/photoAccessHelper-savebutton.md#使用安全控件保存媒体库资源)。 21 22## 保存图片或视频类文件 23 24[PhotoViewPicker](../reference/apis-core-file-kit/js-apis-file-picker.md#photoviewpickerdeprecated)在后续版本不再演进,建议使用[Media Library Kit(媒体文件管理服务)中能力来保存媒体库资源](../media/medialibrary/photoAccessHelper-savebutton.md)。 25 26如果开发场景无法调用安全控件进行图片、视频保存,可使用相册管理模块[PhotoAccessHelper.showAssetsCreationDialog](../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-PhotoAccessHelper.md#showassetscreationdialog12)接口进行保存操作。 27 28## 保存文档类文件 29 301. 模块导入。 31 32 ```ts 33 import { picker } from '@kit.CoreFileKit'; 34 import { fileIo as fs } from '@kit.CoreFileKit'; 35 import { BusinessError } from '@kit.BasicServicesKit'; 36 import { common } from '@kit.AbilityKit'; 37 ``` 38 392. 配置保存选项。 40 41 ```ts 42 // 创建文件管理器选项实例。 43 const documentSaveOptions = new picker.DocumentSaveOptions(); 44 // 保存文件名(可选)。 默认为空。 45 documentSaveOptions.newFileNames = ["DocumentViewPicker01.txt"]; 46 //指定保存的文件或者目录的URI(可选)。 47 documentSaveOptions.defaultFilePathUri = "file://docs/storage/Users/currentUser/test"; 48 // 保存文件类型['后缀类型描述|后缀类型'],选择所有文件:'所有文件(*.*)|.*'(可选) ,如果选择项存在多个后缀(做大限制100个过滤后缀),默认选择第一个。如果不传该参数,默认无过滤后缀。 49 documentSaveOptions.fileSuffixChoices = ['文档|.txt', '.pdf']; 50 ``` 51 523. 创建[文件选择器DocumentViewPicker](../reference/apis-core-file-kit/js-apis-file-picker.md#constructor12)实例。调用[save()](../reference/apis-core-file-kit/js-apis-file-picker.md#save)接口拉起FilePicker界面进行文件保存。 53 54 ```ts 55 let uris: Array<string> = []; 56 // 请在组件内获取context,确保this.getUIContext().getHostContext()返回结果为UIAbilityContext 57 let context = this.getUIContext().getHostContext() as common.UIAbilityContext; 58 const documentViewPicker = new picker.DocumentViewPicker(context); 59 documentViewPicker.save(documentSaveOptions).then((documentSaveResult: Array<string>) => { 60 uris = documentSaveResult; 61 console.info('documentViewPicker.save to file succeed and uris are:' + uris); 62 }).catch((err: BusinessError) => { 63 console.error(`Invoke documentViewPicker.save failed, code is ${err.code}, message is ${err.message}`); 64 }) 65 ``` 66 67 > **注意**: 68 > 69 > 1. URI存储建议: 70 > - 避免在Picker回调中直接操作URI。 71 > - 建议使用全局变量保存URI以供后续使用。 72 > 73 > 2. 快捷保存: 74 > - 可以通过[DOWNLOAD模式](#download模式保存文件)直达下载目录。 75 764. 待界面从FilePicker返回后,使用[基础文件API的fs.openSync](../reference/apis-core-file-kit/js-apis-file-fs.md#fsopensync)接口,通过URI打开这个文件得到文件描述符(fd)。 77 78 ```ts 79 const uri = ''; 80 //这里需要注意接口权限参数是fs.OpenMode.READ_WRITE。 81 let file = fs.openSync(uri, fs.OpenMode.READ_WRITE); 82 console.info('file fd: ' + file.fd); 83 ``` 84 855. 通过(fd)使用[基础文件API的fs.writeSync](../reference/apis-core-file-kit/js-apis-file-fs.md#writesync)接口对这个文件进行编辑修改,编辑修改完成后关闭(fd)。 86 87 ```ts 88 let writeLen: number = fs.writeSync(file.fd, 'hello, world'); 89 console.info('write data to file succeed and size is:' + writeLen); 90 fs.closeSync(file); 91 ``` 92 93## 保存音频类文件 94 951. 模块导入。 96 97 ```ts 98 import { picker } from '@kit.CoreFileKit'; 99 import { fileIo as fs } from '@kit.CoreFileKit'; 100 import { BusinessError } from '@kit.BasicServicesKit'; 101 import { common } from '@kit.AbilityKit'; 102 ``` 103 1042. 配置保存选项。 105 106 ```ts 107 const audioSaveOptions = new picker.AudioSaveOptions(); 108 // 保存文件名(可选) 109 audioSaveOptions.newFileNames = ['AudioViewPicker01.mp3']; 110 ``` 111 1123. 创建[音频选择器AudioViewPicker](../reference/apis-core-file-kit/js-apis-file-picker.md#audioviewpicker)实例。调用[save()](../reference/apis-core-file-kit/js-apis-file-picker.md#save-5)接口拉起FilePicker界面进行文件保存。 113 114 ```ts 115 let uri: string = ''; 116 // 请在组件内获取context,确保this.getUIContext().getHostContext()返回结果为UIAbilityContext 117 let context = this.getUIContext().getHostContext() as common.UIAbilityContext; 118 const audioViewPicker = new picker.AudioViewPicker(context); 119 audioViewPicker.save(audioSaveOptions).then((audioSelectResult: Array<string>) => { 120 uri = audioSelectResult[0]; 121 console.info('audioViewPicker.save to file succeed and uri is:' + uri); 122 }).catch((err: BusinessError) => { 123 console.error(`Invoke audioViewPicker.save failed, code is ${err.code}, message is ${err.message}`); 124 }) 125 ``` 126 127 > **注意**: 128 > 129 > 1. URI存储建议: 130 > - 避免在Picker回调中直接操作URI。 131 > - 建议使用全局变量保存URI以供后续使用。 132 > 133 > 2. 快捷保存: 134 > - 可以通过[DOWNLOAD模式](#download模式保存文件)直达下载目录。 135 1364. 待界面从FilePicker返回后,可以使用[基础文件API的fs.openSync](../reference/apis-core-file-kit/js-apis-file-fs.md#fsopensync)接口,通过URI打开这个文件得到文件描述符(fd)。 137 138 ```ts 139 //这里需要注意接口权限参数是fileIo.OpenMode.READ_WRITE。 140 let file = fs.openSync(uri, fs.OpenMode.READ_WRITE); 141 console.info('file fd: ' + file.fd); 142 ``` 143 1445. 通过(fd)使用[基础文件API的fs.writeSync](../reference/apis-core-file-kit/js-apis-file-fs.md#writesync)接口对这个文件进行编辑修改,编辑修改完成后关闭(fd)。 145 146 ```ts 147 let writeLen = fs.writeSync(file.fd, 'hello, world'); 148 console.info('write data to file succeed and size is:' + writeLen); 149 fs.closeSync(file); 150 151 ``` 152 153## DOWNLOAD模式保存文件 154 155**模式特点** 156 157- 自动创建在`Download/包名/`目录。 158- 跳过文件选择界面直接保存。 159- 返回的URI已具备持久化权限, 用户可在该URI下创建文件。 160 161> **注意:** 162> 163> DOWNLOAD模式创建的目录仅用于保存文件,目录之间无访问隔离,不建议保存应用敏感数据。 164 1651. 模块导入。 166 167 ```ts 168 import { fileUri, picker } from '@kit.CoreFileKit'; 169 import { fileIo as fs } from '@kit.CoreFileKit'; 170 import { BusinessError } from '@kit.BasicServicesKit'; 171 import { common } from '@kit.AbilityKit'; 172 ``` 173 1742. 配置下载模式。 175 176 ```ts 177 const documentSaveOptions = new picker.DocumentSaveOptions(); 178 // 配置保存的模式为DOWNLOAD,若配置了DOWNLOAD模式,此时配置的其他documentSaveOptions参数将不会生效。 179 documentSaveOptions.pickerMode = picker.DocumentPickerMode.DOWNLOAD; 180 ``` 181 1823. 保存到下载目录。 183 184 ```ts 185 let uri: string = ''; 186 // 请在组件内获取context,确保this.getUIContext().getHostContext()返回结果为UIAbilityContext 187 let context = this.getUIContext().getHostContext() as common.UIAbilityContext; 188 const documentViewPicker = new picker.DocumentViewPicker(context); 189 const documentSaveOptions = new picker.DocumentSaveOptions(); 190 documentSaveOptions.pickerMode = picker.DocumentPickerMode.DOWNLOAD; 191 documentViewPicker.save(documentSaveOptions).then((documentSaveResult: Array<string>) => { 192 uri = documentSaveResult[0]; 193 console.info('documentViewPicker.save succeed and uri is:' + uri); 194 const testFilePath = new fileUri.FileUri(uri + '/test.txt').path; 195 const file = fs.openSync(testFilePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE); 196 fs.writeSync(file.fd, 'Hello World!'); 197 fs.closeSync(file.fd); 198 }).catch((err: BusinessError) => { 199 console.error(`Invoke documentViewPicker.save failed, code is ${err.code}, message is ${err.message}`); 200 }) 201 ``` 202