1# Rawfile开发指导 2 3## 场景介绍 4 5开发者可以通过本指导了解在OpenHarmony应用中,如何使用Native Rawfile接口操作Rawfile目录和文件。功能包括文件列表遍历、文件打开、搜索、读取和关闭Rawfile。 664后缀相关接口属于新增接口,新接口支持打开更大的rawfile文件(超过2G以上建议使用),具体请参考:[Rawfile接口介绍](../reference/apis-localization-kit/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_SeekRawFile(const RawFile *rawFile, long offset, int whence) | 指定rawfile内偏移量。 | 19| long OH_ResourceManager_GetRawFileOffset(const RawFile *rawFile) | 获取rawfile偏移量。 | 20| int OH_ResourceManager_ReadRawFile(const RawFile *rawFile, void *buf, size_t length) | 读取rawfile文件内容。 | 21| int64_t OH_ResourceManager_GetRawFileRemainingLength(const RawFile *rawFile) | 获取rawfile文件剩余长度。 | 22| void OH_ResourceManager_CloseRawFile(RawFile *rawFile) | 释放rawfile文件相关资源。 | 23| void OH_ResourceManager_CloseRawDir(RawDir *rawDir) | 释放rawfile目录相关资源。 | 24| bool OH_ResourceManager_GetRawFileDescriptor(const RawFile *rawFile, RawFileDescriptor &descriptor) | 获取rawfile的fd。 | 25| bool OH_ResourceManager_ReleaseRawFileDescriptor(const RawFileDescriptor &descriptor) | 释放rawfile的fd。 | 26| void OH_ResourceManager_ReleaseNativeResourceManager(NativeResourceManager *resMgr) | 释放native resource manager相关资源。 | 27| bool OH_ResourceManager_IsRawDir(const NativeResourceManager *mgr, const char *path) | 判断路径是否是rawfile下的目录 | 28 29 30 31## 函数介绍 32 331. 根据NativeResourceManager实例,使用OH_ResourceManager_OpenRawDir接口获取RawDir实例。 34 35 ```c++ 36 RawDir* rawDir = OH_ResourceManager_OpenRawDir(nativeResourceManager, path.c_str()); 37 ``` 38 392. 根据RawDir实例,使用OH_ResourceManager_GetRawFileCount接口获取对应目录下的rawfile文件总数 。 40 41 ```c++ 42 int count = OH_ResourceManager_GetRawFileCount(rawDir); 43 ``` 44 453. 根据RawDir实例,使用OH_ResourceManager_GetRawFileName接口获取目录下对应index的rawfile文件名。 46 47 ```c++ 48 for (int index = 0; index < count; index++) { 49 std::string fileName = OH_ResourceManager_GetRawFileName(rawDir, index); 50 } 51 ``` 52 534. 根据NativeResourceManager实例,使用OH_ResourceManager_OpenRawFile接口获取指定文件名的RawFile实例 54 55 ```c++ 56 RawFile* rawFile = OH_ResourceManager_OpenRawFile(nativeResourceManager, fileName.c_str()); 57 ``` 58 595. 根据RawFile实例,使用OH_ResourceManager_GetRawFileSize接口获取对应rawfile文件大小。 60 61 ```c++ 62 long rawFileSize = OH_ResourceManager_GetRawFileSize(rawFile); 63 ``` 64 656. 根据RawFile实例,使用OH_ResourceManager_SeekRawFile接口指定rawfile偏移量。 66 67 ```c++ 68 int position = OH_ResourceManager_SeekRawFile(rawFile, 10, 0); 69 int position = OH_ResourceManager_SeekRawFile(rawFile, 0 , 1); 70 int position = OH_ResourceManager_SeekRawFile(rawFile, -10, 2); 71 ``` 72 737. 根据RawFile实例,使用OH_ResourceManager_GetRawFileOffset接口获取rawfile偏移量。 74 75 ```c++ 76 long rawFileOffset = OH_ResourceManager_GetRawFileOffset(rawFile) 77 ``` 78 798. 根据RawFile实例,使用OH_ResourceManager_ReadRawFile接口读取rawfile文件内容。 80 81 ```c++ 82 std::unique_ptr<char[]> mediaData = std::make_unique<char[]>(rawFileSize); 83 long rawFileOffset = OH_ResourceManager_ReadRawFile(rawFile, mediaData.get(), rawFileSize); 84 ``` 85 869. 根据RawFile实例,使用OH_ResourceManager_GetRawFileRemainingLength接口读取rawfile文件的剩余长度。 87 88 ```c++ 89 int64_t rawFileRemainingSize = OH_ResourceManager_GetRawFileRemainingLength(rawFile); 90 ``` 91 9210. 根据RawFile实例,使用OH_ResourceManager_CloseRawFile接口释放rawfile文件相关资源。 93 94 ```c++ 95 OH_ResourceManager_CloseRawFile(rawFile); 96 ``` 97 9811. 根据RawDir实例,使用OH_ResourceManager_CloseRawDir接口释放rawfile目录相关资源。 99 100 ```c++ 101 OH_ResourceManager_CloseRawDir(rawDir); 102 ``` 103 10412. 根据RawFile实例,使用OH_ResourceManager_GetRawFileDescriptor接口获取rawfile的RawFileDescriptor。 105 106 ```c++ 107 RawFileDescriptor descriptor; 108 bool result = OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor); 109 ``` 110 11113. 根据RawFileDescriptor实例,使用OH_ResourceManager_ReleaseRawFileDescriptor接口关闭rawfile的fd。 112 113 ```c++ 114 OH_ResourceManager_ReleaseRawFileDescriptor(descriptor); 115 ``` 116 11714. 根据NativeResourceManager实例,使用OH_ResourceManager_ReleaseNativeResourceManager接口释放native resource manager。 118 119 ```c++ 120 OH_ResourceManager_ReleaseNativeResourceManager(nativeResourceManager); 121 ``` 122 12314. 根据传入的rawfile路径,使用OH_ResourceManager_IsRawDir接口判断是否是目录。 124 125 ```c++ 126 OH_ResourceManager_IsRawDir(nativeResourceManager, path); 127 ``` 128 129## 开发步骤 130 131 以ArkTS侧获取rawfile文件列表、rawfile文件内容、rawfile描述符{fd, offset, length}三种调用方式为例。 132 133**1. 创建工程** 134 135 136 137**2. 添加依赖** 138 139创建完成后,IDE会在工程生成cpp目录,目录有libentry/index.d.ts、hello.cpp、CMakeLists.txt等文件。 140 1411. 打开src/main/cpp/CMakeLists.txt,在target_link_libraries依赖中添加资源的librawfile.z.so以及日志依赖libhilog_ndk.z.so。 142 143 ```c++ 144 target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so librawfile.z.so) 145 ``` 146 1472. 打开src/main/cpp/types/libentry/index.d.ts文件,此文件声明了应用侧函数getFileList、getRawFileContent、getRawFileDescriptor。 148 149 ```c++ 150 import resourceManager from '@ohos.resourceManager'; 151 export const getFileList: (resmgr: resourceManager.ResourceManager, path: string) => Array<String>; 152 export const getRawFileContent: (resmgr: resourceManager.ResourceManager, path: string) => Uint8Array; 153 export const getRawFileDescriptor: (resmgr: resourceManager.ResourceManager, path: string) => resourceManager.RawFileDescriptor; 154 export const isRawDir: (resmgr: resourceManager.ResourceManager, path: string) => Boolean; 155 ``` 156 157**3. 修改源文件** 158 1591. 打开src/main/cpp/hello.cpp文件,文件Init会对当前方法进行初始化映射,这里定义对外接口为getFileList、getRawFileContent、getRawFileDescriptor,映射C++接口分别为GetFileList、GetRawFileContent、GetRawFileDescriptor。 160 161 ```c++ 162 EXTERN_C_START 163 static napi_value Init(napi_env env, napi_value exports) 164 { 165 napi_property_descriptor desc[] = { 166 { "getFileList", nullptr, GetFileList, nullptr, nullptr, nullptr, napi_default, nullptr }, 167 { "getRawFileContent", nullptr, GetRawFileContent, nullptr, nullptr, nullptr, napi_default, nullptr }, 168 { "getRawFileDescriptor", nullptr, GetRawFileDescriptor, nullptr, nullptr, nullptr, napi_default, nullptr }, 169 { "isRawDir", nullptr, IsRawDir, nullptr, nullptr, nullptr, napi_default, nullptr } 170 }; 171 172 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 173 return exports; 174 } 175 EXTERN_C_END 176 ``` 177 1782. 把src/main/cpp/hello.cpp文件中,增加对应的三个方法,如下所示 179 180 ```c++ 181 static napi_value GetFileList(napi_env env, napi_callback_info info) 182 static napi_value GetRawFileContent(napi_env env, napi_callback_info info) 183 static napi_value GetRawFileDescriptor(napi_env env, napi_callback_info info) 184 static napi_value IsRawDir(napi_env env, napi_callback_info info) 185 ``` 186 1873. 在hello.cpp文件中获取Js的资源对象,并转为Native的资源对象,即可调用资源的Native接口,获取rawfile列表、rawfile文件内容以及rawfile描述符{fd, offset, length}三种调用方式示例代码如下: 188 189 ```c++ 190 #include <rawfile/raw_file.h> 191 #include <rawfile/raw_dir.h> 192 #include <rawfile/raw_file_manager.h> 193 194 // 示例一:获取rawfile文件列表 GetFileList 195 static napi_value GetFileList(napi_env env, napi_callback_info info) 196 { 197 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "NDKTest Begin"); 198 size_t requireArgc = 3; 199 size_t argc = 2; 200 napi_value argv[2] = { nullptr }; 201 // 获取参数信息 202 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 203 204 // argv[0]即为函数第一个参数Js资源对象,OH_ResourceManager_InitNativeResourceManager转为Native对象。 205 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 206 207 // 获取函数argv[1],此为为rawfile相对路径 208 size_t strSize; 209 char strBuf[256]; 210 napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); 211 std::string dirName(strBuf, strSize); 212 213 // 获取对应的rawDir指针对象 214 RawDir* rawDir = OH_ResourceManager_OpenRawDir(mNativeResMgr, dirName.c_str()); 215 216 // 获取rawDir下文件及文件夹数量 217 int count = OH_ResourceManager_GetRawFileCount(rawDir); 218 219 // 遍历获取文件名称,并保存 220 std::vector<std::string> tempArray; 221 for(int i = 0; i < count; i++) { 222 std::string filename = OH_ResourceManager_GetRawFileName(rawDir, i); 223 tempArray.emplace_back(filename); 224 } 225 226 napi_value fileList; 227 napi_create_array(env, &fileList); 228 for (size_t i = 0; i < tempArray.size(); i++) { 229 napi_value jsString; 230 napi_create_string_utf8(env, tempArray[i].c_str(), NAPI_AUTO_LENGTH, &jsString); 231 napi_set_element(env, fileList, i, jsString); 232 } 233 234 // 关闭打开的指针对象 235 OH_ResourceManager_CloseRawDir(rawDir); 236 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 237 return fileList; 238 } 239 240 // 示例二:获取rawfile文件内容 GetRawFileContent 241 napi_value CreateJsArrayValue(napi_env env, std::unique_ptr<uint8_t[]> &data, long length) 242 { 243 napi_value buffer; 244 napi_status status = napi_create_external_arraybuffer(env, data.get(), length, 245 [](napi_env env, void *data, void *hint) { 246 delete[] static_cast<char*>(data); 247 }, nullptr, &buffer); 248 if (status != napi_ok) { 249 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "Failed to create external array buffer"); 250 return nullptr; 251 } 252 napi_value result = nullptr; 253 status = napi_create_typedarray(env, napi_uint8_array, length, buffer, 0, &result); 254 if (status != napi_ok) { 255 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "Failed to create media typed array"); 256 return nullptr; 257 } 258 data.release(); 259 return result; 260 } 261 static napi_value GetRawFileContent(napi_env env, napi_callback_info info) 262 { 263 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "GetFileContent Begin"); 264 size_t requireArgc = 3; 265 size_t argc = 2; 266 napi_value argv[2] = { nullptr }; 267 // 获取参数信息 268 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 269 270 // argv[0]即为函数第一个参数Js资源对象,OH_ResourceManager_InitNativeResourceManager转为Native对象。 271 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 272 size_t strSize; 273 char strBuf[256]; 274 napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); 275 std::string filename(strBuf, strSize); 276 277 // 获取rawfile指针对象 278 RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str()); 279 if (rawFile != nullptr) { 280 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "OH_ResourceManager_OpenRawFile success"); 281 } 282 // 获取rawfile大小并申请内存 283 long len = OH_ResourceManager_GetRawFileSize(rawFile); 284 std::unique_ptr<uint8_t[]> data= std::make_unique<uint8_t[]>(len); 285 286 // 一次性读取rawfile全部内容 287 int res = OH_ResourceManager_ReadRawFile(rawFile, data.get(), len); 288 289 // 多次部分读取rawfile, 每次读取100 Byte。获取全部内容 290 // long offset = 0; 291 // while (OH_ResourceManager_GetRawFileRemainingLength(rawFile) > 0) { 292 // OH_ResourceManager_ReadRawFile(rawFile, data.get() + offset, 100); 293 // offset += 100; 294 // } 295 296 // 关闭打开的指针对象 297 OH_ResourceManager_CloseRawFile(rawFile); 298 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 299 // 转为js对象 300 return CreateJsArrayValue(env, data, len); 301 } 302 303 // 示例三:获取rawfile文件描述符 GetRawFileDescriptor 304 napi_value createJsFileDescriptor(napi_env env, RawFileDescriptor &descriptor) 305 { 306 napi_value result; 307 napi_status status = napi_create_object(env, &result); 308 if (status != napi_ok) { 309 return result; 310 } 311 312 napi_value fd; 313 status = napi_create_int32(env, descriptor.fd, &fd); 314 if (status != napi_ok) { 315 return result; 316 } 317 status = napi_set_named_property(env, result, "fd", fd); 318 if (status != napi_ok) { 319 return result; 320 } 321 322 napi_value offset; 323 status = napi_create_int64(env, descriptor.start, &offset); 324 if (status != napi_ok) { 325 return result; 326 } 327 status = napi_set_named_property(env, result, "offset", offset); 328 if (status != napi_ok) { 329 return result; 330 } 331 332 napi_value length; 333 status = napi_create_int64(env, descriptor.length, &length); 334 if (status != napi_ok) { 335 return result; 336 } 337 status = napi_set_named_property(env, result, "length", length); 338 if (status != napi_ok) { 339 return result; 340 } 341 return result; 342 } 343 static napi_value GetRawFileDescriptor(napi_env env, napi_callback_info info) 344 { 345 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "NDKTest GetRawFileDescriptor Begin"); 346 size_t requireArgc = 3; 347 size_t argc = 2; 348 napi_value argv[2] = { nullptr }; 349 // 获取参数信息 350 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 351 352 napi_valuetype valueType; 353 napi_typeof(env, argv[0], &valueType); 354 // 获取native的resourceManager对象 355 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 356 size_t strSize; 357 char strBuf[256]; 358 napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); 359 std::string filename(strBuf, strSize); 360 // 获取rawfile指针对象 361 RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str()); 362 if (rawFile != nullptr) { 363 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "OH_ResourceManager_OpenRawFile success"); 364 } 365 // 获取rawfile的描述符RawFileDescriptor {fd, offset, length} 366 RawFileDescriptor descriptor; 367 OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor); 368 // 关闭打开的指针对象 369 OH_ResourceManager_CloseRawFile(rawFile); 370 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 371 // 转为js对象 372 return createJsFileDescriptor(env,descriptor); 373 } 374 napi_value CreateJsBool(napi_env env, bool &bValue) 375 { 376 napi_value jsValue = nullptr; 377 if (napi_get_boolean(env, bValue, &jsValue) != napi_ok) { 378 return nullptr; 379 } 380 return jsValue; 381 } 382 static napi_value IsRawDir(napi_env env, napi_callback_info info) 383 { 384 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "NDKTest IsRawDir Begin"); 385 size_t requireArgc = 3; 386 size_t argc = 2; 387 napi_value argv[2] = { nullptr }; 388 // 获取参数信息 389 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 390 391 napi_valuetype valueType; 392 napi_typeof(env, argv[0], &valueType); 393 // 获取native的resourceManager对象 394 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 395 396 napi_valuetype valueType1; 397 napi_typeof(env, argv[1], &valueType); 398 if (valueType1 == napi_undefined || valueType1 == napi_null) { 399 bool temp = false; 400 return CreateJsBool(env, temp); 401 } 402 size_t strSize; 403 char strBuf[256]; 404 napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); 405 std::string filename(strBuf, strSize); 406 // 获取rawfile指针对象 407 bool result = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str()); 408 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 409 return CreateJsBool(env, result); 410 } 411 ``` 412 413**4. Js侧调用** 414 4151. 打开src\main\ets\pages\index.ets, 导入"libentry.so"; 416 4172. 资源获取包括获取本应用包资源、应用内跨包资源、跨应用包资源。<br>获取本应用包resourceManager对象,通过.context().resourceManager方法。<br>获取应用内跨包resourceManager对象,通过.context().createModuleContext().resourceManager 方法。<br>获取跨应用包resourceManager对象,通过.context.createModuleContext(bundleName:'bundleName name',moduleName:'module name').resourceManager方法,该方法仅支持系统应用使用。<br>Context的更多使用信息请参考[应用上下文Context](../application-models/application-context-stage.md)。 418 4193. 调用Native接口getFileList即为src/main/cpp/types/libentry/index.d.ts中声明的接口,传入js的资源对象,以及rawfile文件夹的相对路径。 420 421 获取本应用包资源resourceManager对象的示例如下: 422 423 ```js 424 import hilog from '@ohos.hilog'; 425 import testNapi from 'libentry.so' // 导入so 426 @Entry 427 @Component 428 struct Index { 429 @State message: string = 'Hello World' 430 private resmgr = getContext().resourceManager; // 获取本应用包的资源对象 431 build() { 432 Row() { 433 Column() { 434 Text(this.message) 435 .fontSize(50) 436 .fontWeight(FontWeight.Bold) 437 .onClick(() => { 438 hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); 439 let rawfilelist = testNapi.getFileList(this.resmgr, ""); //传入资源对象,以及访问的rawfile文件夹名称 440 console.log("rawfilelist" + rawfilelist); 441 let rawfileContet = testNapi.getRawFileContent(this.resmgr, "rawfile1.txt"); 442 console.log("rawfileContet" + rawfileContet); 443 let rawfileDescriptor = testNapi.getRawFileDescriptor(this.resmgr, "rawfile1.txt"); 444 console.log("getRawFileDescriptor" + rawfileDescriptor.fd, rawfileDescriptor.offset, rawfileDescriptor.length); 445 let ret = testNapi.isRawDir(this.resmgr, "rawfile1.txt"); 446 }) 447 } 448 .width('100%') 449 } 450 .height('100%') 451 } 452 } 453 ``` 454 455## 相关实例 456 457针对资源管理Rawfile开发,有以下相关实例可供参考: 458 459- [获取Rawfile资源(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Native/NdkRawfile) 460