1# 资源管理Rawfile开发指导 2 3## 场景介绍 4 5开发者可以通过本指导了解在OpenHarmony应用中,如何使用Native Rawfile接口操作Rawfile目录和文件。功能包括文件列表遍历、文件打开、搜索、读取和关闭Rawfile。 6 7## 接口说明 8 9| 接口名 | 描述 | 10| :----------------------------------------------------------- | :--------------------------------------- | 11| NativeResourceManager *OH_ResourceManager_InitNativeResourceManager(napi_env env, napi_value jsResMgr) | 初始化native resource manager。 | 12| RawDir *OH_ResourceManager_OpenRawDir(const NativeResourceManager *mgr, const char *dirName) | 打开指定rawfile目录。 | 13| int OH_ResourceManager_GetRawFileCount(RawDir *rawDir) | 获取指定rawfile目录下的rawfile文件数量。 | 14| const char *OH_ResourceManager_GetRawFileName(RawDir *rawDir, int index) | 获取rawfile名字。 | 15| RawFile *OH_ResourceManager_OpenRawFile(const NativeResourceManager *mgr, const char *fileName) | 打开指定rawfile文件。 | 16| long OH_ResourceManager_GetRawFileSize(RawFile *rawFile) | 获取rawfile文件大小。 | 17| int OH_ResourceManager_SeekRawFile(const RawFile *rawFile, long offset, int whence) | 指定rawfile内偏移量。 | 18| long OH_ResourceManager_GetRawFileOffset(const RawFile *rawFile) | 获取rawfile偏移量。 | 19| int OH_ResourceManager_ReadRawFile(const RawFile *rawFile, void *buf, size_t length) | 读取rawfile文件内容。 | 20| void OH_ResourceManager_CloseRawFile(RawFile *rawFile) | 释放rawfile文件相关资源。 | 21| void OH_ResourceManager_CloseRawDir(RawDir *rawDir) | 释放rawfile目录相关资源。 | 22| bool OH_ResourceManager_GetRawFileDescriptor(const RawFile *rawFile, RawFileDescriptor &descriptor) | 获取rawfile的fd。 | 23| bool OH_ResourceManager_ReleaseRawFileDescriptor(const RawFileDescriptor &descriptor) | 释放rawfile的fd。 | 24| void OH_ResourceManager_ReleaseNativeResourceManager(NativeResourceManager *resMgr) | 释放native resource manager相关资源。 | 25 26## 开发步骤 27 28 以Js侧获取rawfile文件列表、rawfile文件内容、rawfile描述符{fd, offset, length}三种调用方式为例。 29 30**1. 创建工程** 31 32![创建C++应用](figures/rawfile1.png) 33 34**2. 添加依赖** 35 36创建完成后,IDE会在工程生成cpp目录,目录有libentry/index.d.ts、hello.cpp、CMakeLists.txt等文件。 37 381. 打开src/main/cpp/CMakeLists.txt,在target_link_libraries依赖中添加资源的librawfile.z.so以及日志依赖libhilog_ndk.z.so 39 40 ```c++ 41 target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so librawfile.z.so) 42 ``` 43 442. 打开src/main/cpp/types/libentry/index.d.ts文件,此文件声明了应用侧函数getFileList、getRawFileContent、getRawFileDescriptor。 45 46 ```c++ 47 import resourceManager from '@ohos.resourceManager'; 48 export const getFileList: (resmgr: resourceManager.ResourceManager, path: string) => Array<String>; 49 export const getRawFileContent: (resmgr: resourceManager.ResourceManager, path: string) => Uint8Array; 50 export const getRawFileDescriptor: (resmgr: resourceManager.ResourceManager, path: string) => resourceManager.RawFileDescriptor; 51 ``` 52 53**3. 修改源文件** 54 551. 打开src/main/cpp/hello.cpp文件,文件Init会对当前方法进行初始化映射,这里定义对外接口为getFileList、getRawFileContent、getRawFileDescriptor,映射C++接口分别为GetFileList、GetRawFileContent、GetRawFileDescriptor。 56 57 ```c++ 58 EXTERN_C_START 59 static napi_value Init(napi_env env, napi_value exports) 60 { 61 napi_property_descriptor desc[] = { 62 { "getFileList", nullptr, GetFileList, nullptr, nullptr, nullptr, napi_default, nullptr }, 63 { "getRawFileContent", nullptr, GetRawFileContent, nullptr, nullptr, nullptr, napi_default, nullptr }, 64 { "getRawFileDescriptor", nullptr, GetRawFileDescriptor, nullptr, nullptr, nullptr, napi_default, nullptr } 65 }; 66 67 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 68 return exports; 69 } 70 EXTERN_C_END 71 ``` 72 732. 把src/main/cpp/hello.cpp文件中,增加对应的三个方法,如下所示 74 75 ```c++ 76 static napi_value GetFileList(napi_env env, napi_callback_info info) 77 static napi_value GetRawFileContent(napi_env env, napi_callback_info info) 78 static napi_value GetRawFileDescriptor(napi_env env, napi_callback_info info) 79 ``` 80 813. 在hello.cpp文件中获取Js的资源对象,并转为Native的资源对象,即可调用资源的Native接口,获取rawfile列表、rawfile文件内容以及rawfile描述符{fd, offset, length}三种调用方式示例代码如下: 82 83 ```c++ 84 // 示例一:获取rawfile文件列表 GetFileList 85 static napi_value GetFileList(napi_env env, napi_callback_info info) 86 { 87 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "NDKTest Begin"); 88 size_t requireArgc = 3; 89 size_t argc = 2; 90 napi_value argv[2] = { nullptr }; 91 // 获取参数信息 92 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 93 94 // argv[0]即为函数第一个参数Js资源对象,OH_ResourceManager_InitNativeResourceManager转为Native对象。 95 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 96 97 // 获取函数argv[1],此为为rawfile相对路径 98 size_t strSize; 99 char strBuf[256]; 100 napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); 101 std::string dirName(strBuf, strSize); 102 103 // 获取对应的rawDir指针对象 104 RawDir* rawDir = OH_ResourceManager_OpenRawDir(mNativeResMgr, dirName.c_str()); 105 106 // 获取rawDir下文件及文件夹数量 107 int count = OH_ResourceManager_GetRawFileCount(rawDir); 108 109 // 遍历获取文件名称,并保存 110 std::vector<std::string> tempArray; 111 for(int i = 0; i < count; i++) { 112 std::string filename = OH_ResourceManager_GetRawFileName(rawDir, i); 113 tempArray.emplace_back(filename); 114 } 115 116 napi_value fileList; 117 napi_create_array(env, &fileList); 118 for (size_t i = 0; i < tempArray.size(); i++) { 119 napi_value jsString; 120 napi_create_string_utf8(env, tempArray[i].c_str(), NAPI_AUTO_LENGTH, &jsString); 121 napi_set_element(env, fileList, i, jsString); 122 } 123 124 // 关闭打开的指针对象 125 OH_ResourceManager_CloseRawDir(rawDir); 126 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 127 return fileList; 128 } 129 130 // 示例二:获取rawfile文件内容 GetRawFileContent 131 napi_value CreateJsArrayValue(napi_env env, std::unique_ptr<uint8_t[]> &data, long length) 132 { 133 napi_value buffer; 134 napi_status status = napi_create_external_arraybuffer(env, data.get(), length, 135 [](napi_env env, void *data, void *hint) { 136 delete[] static_cast<char*>(data); 137 }, nullptr, &buffer); 138 if (status != napi_ok) { 139 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "Failed to create external array buffer"); 140 return nullptr; 141 } 142 napi_value result = nullptr; 143 status = napi_create_typedarray(env, napi_uint8_array, length, buffer, 0, &result); 144 if (status != napi_ok) { 145 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "Failed to create media typed array"); 146 return nullptr; 147 } 148 data.release(); 149 return result; 150 } 151 static napi_value GetRawFileContent(napi_env env, napi_callback_info info) 152 { 153 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "GetFileContent Begin"); 154 size_t requireArgc = 3; 155 size_t argc = 2; 156 napi_value argv[2] = { nullptr }; 157 // 获取参数信息 158 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 159 160 // argv[0]即为函数第一个参数Js资源对象,OH_ResourceManager_InitNativeResourceManager转为Native对象。 161 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 162 size_t strSize; 163 char strBuf[256]; 164 napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); 165 std::string filename(strBuf, strSize); 166 167 // 获取rawfile指针对象 168 RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str()); 169 if (rawFile != nullptr) { 170 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "OH_ResourceManager_OpenRawFile success"); 171 } 172 // 获取rawfile大小并申请内存 173 long len = OH_ResourceManager_GetRawFileSize(rawFile); 174 std::unique_ptr<uint8_t[]> data= std::make_unique<uint8_t[]>(len); 175 // 读取rawfile 176 int res = OH_ResourceManager_ReadRawFile(rawFile, data.get(), len); 177 // 关闭打开的指针对象 178 OH_ResourceManager_CloseRawFile(rawFile); 179 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 180 // 转为js对象 181 return CreateJsArrayValue(env, data, len); 182 } 183 184 // 示例三:获取rawfile文件描述符 GetRawFileDescriptor 185 napi_value createJsFileDescriptor(napi_env env, RawFileDescriptor &descriptor) 186 { 187 napi_value result; 188 napi_status status = napi_create_object(env, &result); 189 if (status != napi_ok) { 190 return result; 191 } 192 193 napi_value fd; 194 status = napi_create_int32(env, descriptor.fd, &fd); 195 if (status != napi_ok) { 196 return result; 197 } 198 status = napi_set_named_property(env, result, "fd", fd); 199 if (status != napi_ok) { 200 return result; 201 } 202 203 napi_value offset; 204 status = napi_create_int64(env, descriptor.start, &offset); 205 if (status != napi_ok) { 206 return result; 207 } 208 status = napi_set_named_property(env, result, "offset", offset); 209 if (status != napi_ok) { 210 return result; 211 } 212 213 napi_value length; 214 status = napi_create_int64(env, descriptor.length, &length); 215 if (status != napi_ok) { 216 return result; 217 } 218 status = napi_set_named_property(env, result, "length", length); 219 if (status != napi_ok) { 220 return result; 221 } 222 return result; 223 } 224 static napi_value GetRawFileDescriptor(napi_env env, napi_callback_info info) 225 { 226 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "NDKTest GetRawFileDescriptor Begin"); 227 size_t requireArgc = 3; 228 size_t argc = 2; 229 napi_value argv[2] = { nullptr }; 230 // 获取参数信息 231 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 232 233 napi_valuetype valueType; 234 napi_typeof(env, argv[0], &valueType); 235 // 获取native的resourceManager对象 236 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 237 size_t strSize; 238 char strBuf[256]; 239 napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); 240 std::string filename(strBuf, strSize); 241 // 获取rawfile指针对象 242 RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str()); 243 if (rawFile != nullptr) { 244 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "OH_ResourceManager_OpenRawFile success"); 245 } 246 // 获取rawfile的描述符RawFileDescriptor {fd, offset, length} 247 RawFileDescriptor descriptor; 248 OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor); 249 // 关闭打开的指针对象 250 OH_ResourceManager_CloseRawFile(rawFile); 251 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 252 // 转为js对象 253 return createJsFileDescriptor(env,descriptor); 254 } 255 ``` 256 257**4. Js侧调用** 258 2591. 打开src\main\ets\pages\index.ets, 导入"libentry.so"; 260 2612. 获取当前js的resourceManager对象; 262 2633. 调用Native接口getFileList即为src/main/cpp/types/libentry/index.d.ts中声明的接口,传入js的资源对象,以及rawfile文件夹的相对路径。示例如下: 264 265 ```js 266 import hilog from '@ohos.hilog'; 267 import testNapi from 'libentry.so' // 导入so 268 @Entry 269 @Component 270 struct Index { 271 @State message: string = 'Hello World' 272 private resmgr = getContext().resourceManager; // 获取js的资源对象 273 build() { 274 Row() { 275 Column() { 276 Text(this.message) 277 .fontSize(50) 278 .fontWeight(FontWeight.Bold) 279 .onClick(() => { 280 hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); 281 let rawfilelist = testNapi.getFileList(this.resmgr, ""); //传入资源对象,以及访问的rawfile文件夹名称 282 console.log("rawfilelist" + rawfilelist); 283 let rawfileContet = testNapi.getRawFileContent(this.resmgr, "rawfile1.txt"); 284 console.log("rawfileContet" + rawfileContet); 285 let rawfileDescriptor = testNapi.getRawFileDescriptor(this.resmgr, "rawfile1.txt"); 286 console.log("getRawFileDescriptor" + rawfileDescriptor.fd, rawfileDescriptor.offset, rawfileDescriptor.length); 287 }) 288 } 289 .width('100%') 290 } 291 .height('100%') 292 } 293 } 294 ``` 295 296## 函数介绍 297 2981. 根据NativeResourceManager实例,使用OH_ResourceManager_OpenRawDir接口获取RawDir实例。 299 300 ```c++ 301 RawDir* rawDir = OH_ResourceManager_OpenRawDir(nativeResourceManager, path.c_str()); 302 ``` 303 3042. 根据RawDir实例,使用OH_ResourceManager_GetRawFileCount接口获取对应目录下的rawfile文件总数 。 305 306 ```c++ 307 int count = OH_ResourceManager_GetRawFileCount(rawDir); 308 ``` 309 3103. 根据RawDir实例,使用OH_ResourceManager_GetRawFileName接口获取目录下对应index的rawfile文件名。 311 312 ```c++ 313 for (int index = 0; index < count; index++) { 314 std::string fileName = OH_ResourceManager_GetRawFileName(rawDir, index); 315 } 316 ``` 317 3184. 根据NativeResourceManager实例,使用OH_ResourceManager_OpenRawFile接口获取指定文件名的RawFile实例 319 320 ```c++ 321 RawFile* rawFile = OH_ResourceManager_OpenRawFile(nativeResourceManager, fileName.c_str()); 322 ``` 323 3245. 根据RawFile实例,使用OH_ResourceManager_GetRawFileSize接口获取对应rawfile文件大小。 325 326 ```c++ 327 long rawFileSize = OH_ResourceManager_GetRawFileSize(rawFile); 328 ``` 329 3306. 根据RawFile实例,使用OH_ResourceManager_SeekRawFile接口指定rawfile偏移量。 331 332 ```c++ 333 int position = OH_ResourceManager_SeekRawFile(rawFile, 10, 0); 334 int position = OH_ResourceManager_SeekRawFile(rawFile, 0 , 1); 335 int position = OH_ResourceManager_SeekRawFile(rawFile, -10, 2); 336 ``` 337 3387. 根据RawFile实例,使用OH_ResourceManager_GetRawFileOffset接口获取rawfile偏移量。 339 340 ```c++ 341 long rawFileOffset = OH_ResourceManager_GetRawFileOffset(rawFile) 342 ``` 343 3448. 根据RawFile实例,使用OH_ResourceManager_ReadRawFile接口读取rawfile文件内容。 345 346 ```c++ 347 std::unique_ptr<char[]> mediaData = std::make_unique<char[]>(rawFileSize); 348 long rawFileOffset = OH_ResourceManager_ReadRawFile(rawFile, mediaData.get(), rawFileSize); 349 ``` 350 3519. 根据RawFile实例,使用OH_ResourceManager_CloseRawFile接口释放rawfile文件相关资源。 352 353 ```c++ 354 OH_ResourceManager_CloseRawFile(rawFile); 355 ``` 356 35710. 根据RawDir实例,使用OH_ResourceManager_CloseRawDir接口释放rawfile目录相关资源。 358 359 ```c++ 360 OH_ResourceManager_CloseRawDir(rawDir); 361 ``` 362 36311. 根据RawFile实例,使用OH_ResourceManager_GetRawFileDescriptor接口获取rawfile的RawFileDescriptor。 364 365 ```c++ 366 RawFileDescriptor descriptor; 367 bool result = OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor); 368 ``` 369 37012. 根据RawFileDescriptor实例,使用OH_ResourceManager_ReleaseRawFileDescriptor接口关闭rawfile的fd。 371 372 ```c++ 373 OH_ResourceManager_ReleaseRawFileDescriptor(descriptor); 374 ``` 375 37613. 根据NativeResourceManager实例,使用OH_ResourceManager_ReleaseNativeResourceManager接口释放native resource manager。 377 378 ```c++ 379 OH_ResourceManager_ReleaseNativeResourceManager(nativeResourceManager); 380 ``` 381 382