1# Rawfile开发指导 2 3## 场景介绍 4 5开发者可以通过本指导了解在OpenHarmony应用中,如何使用Native Rawfile接口操作Rawfile目录和文件。功能包括文件列表遍历、文件打开、搜索、读取和关闭Rawfile。 664后缀相关接口属于新增接口,新接口支持打开更大的rawfile文件(超过2G以上建议使用),具体请参考:[Rawfile接口介绍](../reference/apis-localization-kit/capi-rawfile.md)。64相关的开发步骤和非64一致,将非64接口替换为64接口即可,例如:OH_ResourceManager_OpenRawFile替换为OH_ResourceManager_OpenRawFile64。 7 8## 接口说明 9 10| 接口名 | 描述 | 11| :----------------------------------------------------------- | :--------------------------------------- | 12| NativeResourceManager *OH_ResourceManager_InitNativeResourceManager(napi_env env, napi_value jsResMgr) | 初始化native resource manager。 | 13| RawDir *OH_ResourceManager_OpenRawDir(const NativeResourceManager *mgr, const char *dirName) | 打开指定rawfile目录。 | 14| int OH_ResourceManager_GetRawFileCount(RawDir *rawDir) | 获取指定rawfile目录下的rawfile文件数量。 | 15| const char *OH_ResourceManager_GetRawFileName(RawDir *rawDir, int index) | 获取rawfile名字。 | 16| RawFile *OH_ResourceManager_OpenRawFile(const NativeResourceManager *mgr, const char *fileName) | 打开指定rawfile文件。 | 17| long OH_ResourceManager_GetRawFileSize(RawFile *rawFile) | 获取rawfile文件大小。 | 18| int OH_ResourceManager_ReadRawFile(const RawFile *rawFile, void *buf, size_t length) | 读取rawfile文件内容。 | 19| void OH_ResourceManager_CloseRawFile(RawFile *rawFile) | 释放rawfile文件相关资源。 | 20| void OH_ResourceManager_CloseRawDir(RawDir *rawDir) | 释放rawfile目录相关资源。 | 21| bool OH_ResourceManager_GetRawFileDescriptor(const RawFile *rawFile, RawFileDescriptor &descriptor) | 获取rawfile的fd。 | 22| void OH_ResourceManager_ReleaseNativeResourceManager(NativeResourceManager *resMgr) | 释放native resource manager相关资源。 | 23| bool OH_ResourceManager_IsRawDir(const NativeResourceManager *mgr, const char *path) | 判断路径是否是rawfile下的目录。 | 24 25详细的接口说明请参考[rawfile](../reference/apis-localization-kit/capi-rawfile.md)。 26 27## 开发步骤 28 29 以ArkTS侧获取rawfile文件列表、获取rawfile文件内容、获取rawfile描述符(fd, offset, length)、判断是否是rawfile下的目录四种调用方式为例。 30 31**1. 创建工程** 32 33 34 35**2. 添加依赖** 36 37创建完成后,DevEco Studio会在工程生成cpp目录,目录下有libentry/index.d.ts、hello.cpp、CMakeLists.txt等文件。 38 391. 打开src/main/cpp/CMakeLists.txt,在target_link_libraries依赖中添加rawfile依赖librawfile.z.so以及日志依赖libhilog_ndk.z.so。 40 41 ```c++ 42 target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so librawfile.z.so) 43 ``` 44 452. 打开src/main/cpp/types/libentry/index.d.ts文件,在此文件中声明ArkTS侧接口getFileList、getRawFileContent、getRawFileDescriptor、isRawDir。 46 47 ```js 48 import resourceManager from '@ohos.resourceManager'; 49 export const getFileList: (resmgr: resourceManager.ResourceManager, path: string) => Array<String>; 50 export const getRawFileContent: (resmgr: resourceManager.ResourceManager, path: string) => Uint8Array; 51 export const getRawFileDescriptor: (resmgr: resourceManager.ResourceManager, path: string) => resourceManager.RawFileDescriptor; 52 export const isRawDir: (resmgr: resourceManager.ResourceManager, path: string) => boolean; 53 ``` 54 55**3. 修改源文件** 56 571. 打开src/main/cpp/hello.cpp文件,在Init方法中添加ArkTS接口与C++接口的映射。ArkTS侧接口getFileList、getRawFileContent、getRawFileDescriptor、isRawDir,映射C++接口分别为GetFileList、GetRawFileContent、GetRawFileDescriptor、IsRawDir。 58 59 ```c++ 60 EXTERN_C_START 61 static napi_value Init(napi_env env, napi_value exports) 62 { 63 napi_property_descriptor desc[] = { 64 { "getFileList", nullptr, GetFileList, nullptr, nullptr, nullptr, napi_default, nullptr }, 65 { "getRawFileContent", nullptr, GetRawFileContent, nullptr, nullptr, nullptr, napi_default, nullptr }, 66 { "getRawFileDescriptor", nullptr, GetRawFileDescriptor, nullptr, nullptr, nullptr, napi_default, nullptr }, 67 { "isRawDir", nullptr, IsRawDir, nullptr, nullptr, nullptr, napi_default, nullptr } 68 }; 69 70 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 71 return exports; 72 } 73 EXTERN_C_END 74 ``` 75 <!-- @[module_registration](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ResourceManagement/RawFile/entry/src/main/cpp/hello.cpp) --> 76 772. 在src/main/cpp/hello.cpp文件中,增加对应的四个方法,如下所示: 78 79 ```c++ 80 static napi_value GetFileList(napi_env env, napi_callback_info info) 81 static napi_value GetRawFileContent(napi_env env, napi_callback_info info) 82 static napi_value GetRawFileDescriptor(napi_env env, napi_callback_info info) 83 static napi_value IsRawDir(napi_env env, napi_callback_info info) 84 ``` 85 863. 在hello.cpp文件中实现上述四个方法。通过env和info获取Js的资源管理对象,并转换为Native的资源管理对象,即可调用Native资源管理对象的接口,示例代码如下: 87 88 导入头文件 89 ```c++ 90 #include <js_native_api.h> 91 #include <js_native_api_types.h> 92 #include <string> 93 #include <vector> 94 #include <cstdlib> 95 #include "napi/native_api.h" 96 #include "rawfile/raw_file_manager.h" 97 #include "rawfile/raw_file.h" 98 #include "rawfile/raw_dir.h" 99 #include "hilog/log.h" 100 ``` 101 <!-- @[includes](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ResourceManagement/RawFile/entry/src/main/cpp/hello.cpp) --> 102 103 声明hilog日志打印的DOMAIN和TAG常量 104 ```c++ 105 const int GLOBAL_RESMGR = 0xFF00; 106 const char *TAG = "[Sample_rawfile]"; 107 ``` 108 <!-- @[constants](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ResourceManagement/RawFile/entry/src/main/cpp/hello.cpp) --> 109 110 示例: 111 ```c++ 112 // 示例一:获取rawfile文件列表 GetFileList 113 static napi_value GetFileList(napi_env env, napi_callback_info info) 114 { 115 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "NDKTest GetFileList Begin"); 116 size_t argc = 2; 117 napi_value argv[2] = { nullptr }; 118 // 获取参数信息 119 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 120 121 // argv[0]即为函数第一个参数Js资源对象,OH_ResourceManager_InitNativeResourceManager转为Native对象 122 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 123 124 // 获取函数argv[1],此为rawfile相对路径 125 size_t strSize; 126 char strBuf[256]; 127 napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); 128 std::string dirName(strBuf, strSize); 129 130 // 获取对应的rawDir指针对象 131 RawDir* rawDir = OH_ResourceManager_OpenRawDir(mNativeResMgr, dirName.c_str()); 132 133 // 获取rawDir下文件及文件夹数量 134 int count = OH_ResourceManager_GetRawFileCount(rawDir); 135 136 // 遍历获取文件名称,并保存 137 std::vector<std::string> tempArray; 138 for (int i = 0; i < count; i++) { 139 std::string filename = OH_ResourceManager_GetRawFileName(rawDir, i); 140 tempArray.emplace_back(filename); 141 } 142 143 // 转为js数组 144 napi_value fileList; 145 napi_create_array(env, &fileList); 146 for (size_t i = 0; i < tempArray.size(); i++) { 147 napi_value jsString; 148 napi_create_string_utf8(env, tempArray[i].c_str(), NAPI_AUTO_LENGTH, &jsString); 149 napi_set_element(env, fileList, i, jsString); 150 } 151 152 // 关闭打开的指针对象 153 OH_ResourceManager_CloseRawDir(rawDir); 154 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 155 return fileList; 156 } 157 ``` 158 <!-- @[example_get_file_list](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ResourceManagement/RawFile/entry/src/main/cpp/hello.cpp) --> 159 160 161 ```c++ 162 // 示例二:获取rawfile文件内容 GetRawFileContent 163 napi_value CreateJsArrayValue(napi_env env, std::unique_ptr<uint8_t[]> &data, long length) 164 { 165 // 创建js外部ArrayBuffer 166 napi_value buffer; 167 napi_status status = napi_create_external_arraybuffer(env, data.get(), length, 168 [](napi_env env, void *data, void *hint) { 169 delete[] static_cast<char*>(data); 170 }, nullptr, &buffer); 171 // 检测ArrayBuffer是否创建成功 172 if (status != napi_ok) { 173 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, TAG, "Failed to create external array buffer"); 174 return nullptr; 175 } 176 // 创建js TypedArray 将ArrayBuffer绑定到TypedArray 177 napi_value result = nullptr; 178 status = napi_create_typedarray(env, napi_uint8_array, length, buffer, 0, &result); 179 if (status != napi_ok) { 180 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, TAG, "Failed to create media typed array"); 181 return nullptr; 182 } 183 data.release(); 184 return result; 185 } 186 187 static napi_value GetRawFileContent(napi_env env, napi_callback_info info) 188 { 189 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "GetFileContent Begin"); 190 size_t argc = 2; 191 napi_value argv[2] = { nullptr }; 192 // 获取参数信息 193 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 194 195 // argv[0]即为函数第一个参数Js资源对象,OH_ResourceManager_InitNativeResourceManager转为Native对象 196 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 197 size_t strSize; 198 char strBuf[256]; 199 napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); 200 std::string filename(strBuf, strSize); 201 202 // 获取rawfile指针对象 203 RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str()); 204 if (rawFile != nullptr) { 205 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "OH_ResourceManager_OpenRawFile success"); 206 } 207 // 获取rawfile大小并申请内存 208 long len = OH_ResourceManager_GetRawFileSize(rawFile); 209 std::unique_ptr<uint8_t[]> data = std::make_unique<uint8_t[]>(len); 210 211 // 一次性读取rawfile全部内容 212 int res = OH_ResourceManager_ReadRawFile(rawFile, data.get(), len); 213 214 // 关闭打开的指针对象 215 OH_ResourceManager_CloseRawFile(rawFile); 216 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 217 // 转为js对象 218 return CreateJsArrayValue(env, data, len); 219 } 220 ``` 221 <!-- @[example_get_rawfile_content](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ResourceManagement/RawFile/entry/src/main/cpp/hello.cpp) --> 222 223 224 ```c++ 225 // 示例三:获取rawfile文件描述符 GetRawFileDescriptor 226 // 定义一个函数,将RawFileDescriptor转为js对象 227 napi_value createJsFileDescriptor(napi_env env, RawFileDescriptor& descriptor) 228 { 229 // 创建js对象 230 napi_value result; 231 napi_status status = napi_create_object(env, &result); 232 if (status != napi_ok) { 233 return result; 234 } 235 236 // 将文件描述符df存入到result对象中 237 napi_value fd; 238 status = napi_create_int32(env, descriptor.fd, &fd); 239 if (status != napi_ok) { 240 return result; 241 } 242 status = napi_set_named_property(env, result, "fd", fd); 243 if (status != napi_ok) { 244 return result; 245 } 246 247 // 将文件偏移量offset存入到result对象中 248 napi_value offset; 249 status = napi_create_int64(env, descriptor.start, &offset); 250 if (status != napi_ok) { 251 return result; 252 } 253 status = napi_set_named_property(env, result, "offset", offset); 254 if (status != napi_ok) { 255 return result; 256 } 257 258 // 将文件长度length存入到result对象中 259 napi_value length; 260 status = napi_create_int64(env, descriptor.length, &length); 261 if (status != napi_ok) { 262 return result; 263 } 264 status = napi_set_named_property(env, result, "length", length); 265 if (status != napi_ok) { 266 return result; 267 } 268 return result; 269 } 270 271 static napi_value GetRawFileDescriptor(napi_env env, napi_callback_info info) 272 { 273 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "NDKTest GetRawFileDescriptor Begin"); 274 size_t argc = 2; 275 napi_value argv[2] = { nullptr }; 276 // 获取参数信息 277 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 278 279 // argv[0]即为函数第一个参数Js资源对象,OH_ResourceManager_InitNativeResourceManager转为Native对象 280 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 281 size_t strSize; 282 char strBuf[256]; 283 napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); 284 std::string filename(strBuf, strSize); 285 // 获取rawfile指针对象 286 RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str()); 287 if (rawFile != nullptr) { 288 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "OH_ResourceManager_OpenRawFile success"); 289 } 290 // 获取rawfile的描述符RawFileDescriptor {fd, offset, length} 291 RawFileDescriptor descriptor; 292 OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor); 293 // 关闭打开的指针对象 294 OH_ResourceManager_CloseRawFile(rawFile); 295 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 296 // 转为js对象 297 return createJsFileDescriptor(env, descriptor); 298 } 299 ``` 300 <!-- @[example_get_rawfile_descriptor](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ResourceManagement/RawFile/entry/src/main/cpp/hello.cpp) --> 301 302 303 ```c++ 304 // 示例四:判断路径是否是rawfile下的目录 IsRawDir 305 napi_value CreateJsBool(napi_env env, bool &bValue) 306 { 307 napi_value jsValue = nullptr; 308 if (napi_get_boolean(env, bValue, &jsValue) != napi_ok) { 309 return nullptr; 310 } 311 return jsValue; 312 } 313 314 static napi_value IsRawDir(napi_env env, napi_callback_info info) 315 { 316 OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "NDKTest IsRawDir Begin"); 317 size_t argc = 2; 318 napi_value argv[2] = { nullptr }; 319 // 获取参数信息 320 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 321 322 // argv[0]即为函数第一个参数Js资源对象,OH_ResourceManager_InitNativeResourceManager转为Native对象 323 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 324 325 napi_valuetype fileNameType; 326 napi_typeof(env, argv[1], &fileNameType); 327 if (fileNameType == napi_undefined || fileNameType == napi_null) { 328 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, TAG, "NDKTest file name is null"); 329 bool temp = false; 330 return CreateJsBool(env, temp); 331 } 332 size_t strSize; 333 char strBuf[256]; 334 napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); 335 std::string filename(strBuf, strSize); 336 // 判断是否是rawfile下的目录 337 bool result = OH_ResourceManager_IsRawDir(mNativeResMgr, filename.c_str()); 338 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 339 return CreateJsBool(env, result); 340 } 341 ``` 342 <!-- @[example_is_raw_dir](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ResourceManagement/RawFile/entry/src/main/cpp/hello.cpp) --> 343 344**4. ArkTS侧调用** 345 3461. 打开src\main\ets\pages\index.ets, 导入"libentry.so"。 347 3482. 资源获取包括获取本应用包资源、应用内跨包资源、跨应用包资源。<br>通过context.resourceManager获取本应用包resourceManager对象。<br>通过context.createModuleContext().resourceManager获取应用内跨包resourceManager对象。<!--Del--><br>通过context.createModuleContext(bundleName: 'bundleName name', moduleName: 'module name').resourceManager获取跨应用包resourceManager对象,该方法仅支持系统应用使用。<!--DelEnd--><br>Context的更多使用信息请参考[应用上下文Context](../application-models/application-context-stage.md)。 349 3503. 调用src/main/cpp/types/libentry/index.d.ts中声明的接口,如getFileList,传入js的资源管理对象以及rawfile文件夹的相对路径。 351 352 获取本应用包资源resourceManager对象的示例如下: 353 354 ```js 355 import { util } from '@kit.ArkTS'; 356 import { resourceManager } from '@kit.LocalizationKit'; 357 import testNapi from 'libentry.so'; // 导入so 358 359 @Entry 360 @Component 361 struct Index { 362 @State message: string = 'Hello World'; 363 private resMgr = this.getUIContext().getHostContext()?.resourceManager; // 获取本应用包的资源对象 364 @State rawfileListMsg: string = 'FileList = '; 365 @State retMsg: string = 'isRawDir = '; 366 @State rawfileContentMsg: string = 'RawFileContent = '; 367 @State rawfileDescriptorMsg: string = 'RawFileDescriptor.length = '; 368 369 build() { 370 Row() { 371 Column() { 372 Text(this.message) 373 .id('hello_world') 374 .fontSize(30) 375 .fontWeight(FontWeight.Bold) 376 .onClick(async () => { 377 // 传入资源管理对象,以及访问的rawfile文件夹名称 378 let rawFileList: Array<String> = testNapi.getFileList(this.resMgr, ''); 379 this.rawfileListMsg = 'FileList = ' + rawFileList; 380 console.log(this.rawfileListMsg); 381 382 let ret: boolean = testNapi.isRawDir(this.resMgr, 'subrawfile'); 383 this.retMsg = 'isRawDir = ' + ret; 384 console.log(this.retMsg); 385 386 // 传入资源管理对象,以及访问的rawfile文件夹名称 387 let rawfileArray: Uint8Array = testNapi.getRawFileContent(this.resMgr, 'rawfile1.txt'); 388 // 将Uint8Array转为字符串 389 let textDecoder: util.TextDecoder = new util.TextDecoder(); 390 let rawfileContent: string = textDecoder.decodeToString(rawfileArray); 391 this.rawfileContentMsg = 'RawFileContent = ' + rawfileContent; 392 console.log(this.rawfileContentMsg); 393 394 // 传入资源管理对象,以及访问的rawfile文件名称 395 let rawfileDescriptor: resourceManager.RawFileDescriptor = 396 testNapi.getRawFileDescriptor(this.resMgr, 'rawfile1.txt'); 397 this.rawfileDescriptorMsg = 'RawFileDescriptor.length = ' + rawfileDescriptor.length; 398 console.log(this.rawfileDescriptorMsg); 399 }) 400 Text(this.rawfileListMsg).id('get_file_list').fontSize(30); 401 Text(this.retMsg).id('is_raw_dir').fontSize(30); 402 Text(this.rawfileContentMsg).id('get_raw_file_content').fontSize(30); 403 Text(this.rawfileDescriptorMsg).id('get_raw_file_descriptor').fontSize(30); 404 } 405 .width('100%') 406 } 407 .height('100%') 408 } 409 } 410 ``` 411 <!-- @[native_rawfile_guide_sample](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ResourceManagement/RawFile/entry/src/main/ets/pages/Index.ets) --> 412 413## 相关实例 414 415针对资源管理Rawfile开发,有以下相关实例可供参考: 416 417- [获取Rawfile资源(API9)](https://gitcode.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Native/NdkRawfile) 418