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 9OpenHarmony预置了FileManager文件管理器。系统应用开发者也可以根据需要,按以下指导自行开发文件管理器。 10 11## 开发步骤 12开发用户文件管理器的相关API详细介绍请参见[API参考](../reference/apis-core-file-kit/js-apis-fileAccess-sys.md)。 13 141. 权限配置和导入模块。 15 申请ohos.permission.FILE_ACCESS_MANAGER和ohos.permission.GET_BUNDLE_INFO_PRIVILEGED权限,配置方式请参见[申请应用权限](../security/AccessToken/determine-application-mode.md#system_basic等级应用申请权限的方式)。 16 17 > **说明:** 18 > 19 > ohos.permission.FILE_ACCESS_MANAGER是使用文件访问框架接口的基础权限。 20 > 21 > ohos.permission.GET_BUNDLE_INFO_PRIVILEGED权限可以用于查询系统内当前支持的文件管理服务端应用信息。 22 232. 导入依赖模块。 24 25 ```ts 26 import { fileAccess } from '@kit.CoreFileKit'; 27 import { fileExtensionInfo } from '@kit.CoreFileKit'; 28 ``` 29 30 其中fileAccess提供了文件基础操作的API,fileExtensionInfo提供了应用开发的关键结构体。 31 323. 查询设备列表。 33 开发者可以获取当前系统所有文件管理服务端管理的设备属性,也可以获取某个文件管理服务端管理的设备属性。应用开发者可以按需过滤设备。 34 35 在文件访问框架中,使用RootInfo用于表示设备的属性信息。以下示例可以获取所有设备的RootInfo。 36 37 ```ts 38 import { common } from '@kit.AbilityKit'; 39 import { BusinessError } from '@kit.BasicServicesKit'; 40 import { Filter } from '@kit.CoreFileKit'; 41 42 // context是EntryAbility传过来的context,确保this.getUIContext().getHostContext()返回结果为UIAbilityContext 43 let context = this.getUIContext().getHostContext() as common.UIAbilityContext; 44 45 // 创建连接系统内所有文件管理服务端的helper对象 46 let fileAccessHelperAllServer: fileAccess.FileAccessHelper; 47 function createFileAccessHelper(context: common.UIAbilityContext): void { 48 try { 49 fileAccessHelperAllServer = fileAccess.createFileAccessHelper(context); 50 if (!fileAccessHelperAllServer) { 51 console.error("createFileAccessHelper interface returns an undefined object"); 52 } 53 } catch (err) { 54 let error: BusinessError = err as BusinessError; 55 console.error("createFileAccessHelper failed, errCode:" + error.code + ", errMessage:" + error.message); 56 } 57 } 58 let rootInfos: Array<fileAccess.RootInfo> = []; 59 async function getRoots(): Promise<void>{ 60 let rootIterator: fileAccess.RootIterator; 61 let isDone: boolean = false; 62 try { 63 rootIterator = await fileAccessHelperAllServer.getRoots(); 64 if (!rootIterator) { 65 console.error("getRoots interface returns an undefined object"); 66 return; 67 } 68 while (!isDone) { 69 let result = rootIterator.next(); 70 console.info("next result = " + JSON.stringify(result)); 71 isDone = result.done; 72 if (!isDone) 73 rootInfos.push(result.value); 74 } 75 } catch (err) { 76 let error: BusinessError = err as BusinessError; 77 console.error("getRoots failed, errCode:" + error.code + ", errMessage:" + error.message); 78 } 79 } 80 ``` 81 824. 浏览目录。 83 在文件访问框架中,使用FileInfo表示一个文件(目录)的基础信息。开发者可以使用listfile接口遍历下一级所有文件(目录)的迭代器对象;也可以通过scanfile过滤指定目录,获取满足条件的迭代器对象。 84 85 listfile和scanfile接口当前支持RootInfo对象调用,可用于支撑遍历下一级文件或过滤整个目录树。同时,接口也支持FileInfo对象调用,用于支撑遍历下一级文件或过滤指定目录。 86 87 ```ts 88 import { BusinessError } from '@kit.BasicServicesKit'; 89 import { Filter } from '@kit.CoreFileKit'; 90 91 // 从根目录开始 92 let rootInfos = []; 93 //rootInfos 从getRoots()获取 94 let rootInfo: fileAccess.RootInfo = rootInfos[0]; 95 let fileInfos: Array<fileAccess.FileInfo> = []; 96 let isDone: boolean = false; 97 let filter: Filter = {suffix : [".txt", ".jpg", ".xlsx"]}; // 设定过滤条件 98 try { 99 let fileIterator = rootInfo.listFile(); // 遍历设备rootinfos[0]的根目录,返回迭代器对象 100 // let fileIterator = rootInfo.scanFile(filter); // 过滤设备rootinfos[0]满足指定条件的文件信息,返回迭代对象 101 if (!fileIterator) { 102 console.error("listFile interface returns an undefined object"); 103 } 104 while (!isDone) { 105 let result = fileIterator.next(); 106 console.info("next result = " + JSON.stringify(result)); 107 isDone = result.done; 108 if (!isDone) 109 fileInfos.push(result.value); 110 } 111 } catch (err) { 112 let error: BusinessError = err as BusinessError; 113 console.error("listFile failed, errCode:" + error.code + ", errMessage:" + error.message); 114 } 115 116 // 从指定的目录开始 117 let fileInfoDir: fileAccess.FileInfo = fileInfos[0]; // fileInfoDir 表示某个目录信息 118 let subFileInfos: Array<fileAccess.FileInfo> = []; 119 let isDone02: boolean = false; 120 let filter02: Filter = {suffix : [".txt", ".jpg", ".xlsx"]}; // 设定过滤条件 121 try { 122 let fileIterator = fileInfoDir.listFile(); // 遍历特定的目录fileinfo,返回迭代器对象 123 // let fileIterator = rootInfo.scanFile(filter02); // 过滤特定的目录fileinfo,返回迭代器对象 124 if (!fileIterator) { 125 console.error("listFile interface returns an undefined object"); 126 } 127 while (!isDone02) { 128 let result = fileIterator.next(); 129 console.info("next result = " + JSON.stringify(result)); 130 isDone02 = result.done; 131 if (!isDone02) 132 subFileInfos.push(result.value); 133 } 134 } catch (err) { 135 let error: BusinessError = err as BusinessError; 136 console.error("listFile failed, errCode:" + error.code + ", errMessage:" + error.message); 137 } 138 ``` 139 1405. 操作文件或目录。 141 开发者可以集成文件访问框架的接口,完成一些用户行为,比如删除文件(目录)、重命名文件(目录)、新建文件(目录)、移动文件(目录)等。以下示例展示了如何创建一个文件,其他接口请参见[API参考](../reference/apis-core-file-kit/js-apis-fileAccess-sys.md)。 142 143 ```ts 144 import { BusinessError } from '@kit.BasicServicesKit'; 145 146 // 以本地设备为例 147 // 创建文件 148 // 示例代码sourceUri是Download目录的fileinfo中的URI 149 // 开发者应根据自己实际获取fileinfo的URI进行开发 150 async function createFile(): Promise<void> { 151 let sourceUri: string = "file://docs/storage/Users/currentUser/Download"; 152 let displayName: string = "file1"; 153 let fileUri: string = ''; 154 try { 155 // fileAccessHelperAllServer 参考 fileAccess.createFileAccessHelper 示例代码获取 156 fileUri = await fileAccessHelperAllServer.createFile(sourceUri, displayName); 157 if (!fileUri) { 158 console.error("createFile return undefined object"); 159 } 160 console.info("createFile sucess, fileUri: " + JSON.stringify(fileUri)); 161 } catch (err) { 162 let error: BusinessError = err as BusinessError; 163 console.error("createFile failed, errCode:" + error.code + ", errMessage:" + error.message); 164 }; 165 } 166 ``` 167 168## 监听设备上下线 169 170开发设备上下线的相关API详细介绍请参见[API参考](../reference/apis-core-file-kit/js-apis-fileAccess-sys.md)。 171 172notify接口不仅可以用来监听目录的变化,还能监听设备上线,下线功能。 173 174 1751. 权限配置和导入模块。 176 177 申请ohos.permission.FILE_ACCESS_MANAGER和ohos.permission.GET_BUNDLE_INFO_PRIVILEGED权限,配置方式请参见[访问控制授权申请](../security/AccessToken/declare-permissions.md)。 178 179 > **说明:** 180 > 181 > ohos.permission.FILE_ACCESS_MANAGER是使用文件访问框架接口的基础权限。 182 > 183 > ohos.permission.GET_BUNDLE_INFO_PRIVILEGED权限可以用于查询系统内当前支持的文件管理服务端应用信息。 184 1852. 导入依赖模块。 186 187 ```ts 188 import { fileAccess } from '@kit.CoreFileKit'; 189 import { fileExtensionInfo } from '@kit.CoreFileKit'; 190 ``` 191 192 其中fileAccess提供了文件基础操作的API,fileExtensionInfo提供了应用开发的关键结构体。 193 1943. 提供监听回调方法。 195 196 ```ts 197 const callbackDir1 = (NotifyMessageDir: fileAccess.NotifyMessage) => { 198 if (NotifyMessageDir != undefined) { 199 console.log('NotifyType: ' + NotifyMessageDir.type + 'NotifyUri:' + NotifyMessageDir.uris[0]); 200 } else { 201 console.error("NotifyMessageDir is undefined"); 202 } 203 } 204 ``` 205 2064. 注册监听设备和取消设备监听。 207 208 开发者可以根据提供的[DEVICES_URI](../reference/apis-core-file-kit/js-apis-fileAccess-sys.md#常量),传入方法registerObserver()中,就能监听设备上下线状态。传入方法unregisterObserver()中,就能取消设备上线,下线状态。 209 210 ```ts 211 import { BusinessError } from '@kit.BasicServicesKit'; 212 import { common } from '@kit.AbilityKit'; 213 214 //提供监听回调方法 215 const callbackDir1 = (NotifyMessageDir: fileAccess.NotifyMessage) => { 216 if (NotifyMessageDir != undefined) { 217 console.log('NotifyType: ' + NotifyMessageDir.type + 'NotifyUri:' + NotifyMessageDir.uris[0]); 218 } else { 219 console.error("NotifyMessageDir is undefined"); 220 } 221 } 222 223 // context是EntryAbility传过来的context,确保this.getUIContext().getHostContext()返回结果为UIAbilityContext 224 let context = this.getUIContext().getHostContext() as common.UIAbilityContext; 225 // 创建连接系统内所有文件管理服务端的helper对象 226 let fileAccessHelperAllServer: fileAccess.FileAccessHelper; 227 function createFileAccessHelper(context: common.UIAbilityContext): void { 228 try { 229 fileAccessHelperAllServer = fileAccess.createFileAccessHelper(context); 230 if (!fileAccessHelperAllServer) { 231 console.error("createFileAccessHelper interface returns an undefined object"); 232 } 233 } catch (err) { 234 let error: BusinessError = err as BusinessError; 235 console.error("createFileAccessHelper failed, errCode:" + error.code + ", errMessage:" + error.message); 236 } 237 } 238 //注册监听设备,开发者可以根据提供的DEVICES_URI传入registerObserver()方法中,就能监听设备上线,下线状态。 239 async function RegisterObserver03() { 240 try { 241 // 监听设备的上下线 242 fileAccessHelperAllServer.registerObserver(fileAccess.DEVICES_URI, true, callbackDir1); 243 } catch (err) { 244 let error: BusinessError = err as BusinessError; 245 console.error("unregisterObserver failed, errCode:" + error.code + ", errMessage:" + error.message); 246 } 247 } 248 //取消设备监听,开发者可以根据提供的DEVICES_URI传入unregisterObserver()方法中,就能取消设备上线,下线状态。 249 async function UnregisterObserver04() { 250 try { 251 // 取消监听设备的上下线 252 fileAccessHelperAllServer.unregisterObserver(fileAccess.DEVICES_URI, callbackDir1); 253 } catch (err) { 254 let error: BusinessError = err as BusinessError; 255 console.error("unregisterObserver failed, errCode:" + error.code + ", errMessage:" + error.message); 256 } 257 } 258 ``` 259