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| int64_t OH_ResourceManager_GetRawFileRemainingLength(const RawFile *rawFile) | 获取rawfile文件剩余长度。 | 21| void OH_ResourceManager_CloseRawFile(RawFile *rawFile) | 释放rawfile文件相关资源。 | 22| void OH_ResourceManager_CloseRawDir(RawDir *rawDir) | 释放rawfile目录相关资源。 | 23| bool OH_ResourceManager_GetRawFileDescriptor(const RawFile *rawFile, RawFileDescriptor &descriptor) | 获取rawfile的fd。 | 24| bool OH_ResourceManager_ReleaseRawFileDescriptor(const RawFileDescriptor &descriptor) | 释放rawfile的fd。 | 25| void OH_ResourceManager_ReleaseNativeResourceManager(NativeResourceManager *resMgr) | 释放native resource manager相关资源。 | 26 27## 函数介绍 28 291. 根据NativeResourceManager实例,使用OH_ResourceManager_OpenRawDir接口获取RawDir实例。 30 31 ```c++ 32 RawDir* rawDir = OH_ResourceManager_OpenRawDir(nativeResourceManager, path.c_str()); 33 ``` 34 352. 根据RawDir实例,使用OH_ResourceManager_GetRawFileCount接口获取对应目录下的rawfile文件总数 。 36 37 ```c++ 38 int count = OH_ResourceManager_GetRawFileCount(rawDir); 39 ``` 40 413. 根据RawDir实例,使用OH_ResourceManager_GetRawFileName接口获取目录下对应index的rawfile文件名。 42 43 ```c++ 44 for (int index = 0; index < count; index++) { 45 std::string fileName = OH_ResourceManager_GetRawFileName(rawDir, index); 46 } 47 ``` 48 494. 根据NativeResourceManager实例,使用OH_ResourceManager_OpenRawFile接口获取指定文件名的RawFile实例 50 51 ```c++ 52 RawFile* rawFile = OH_ResourceManager_OpenRawFile(nativeResourceManager, fileName.c_str()); 53 ``` 54 555. 根据RawFile实例,使用OH_ResourceManager_GetRawFileSize接口获取对应rawfile文件大小。 56 57 ```c++ 58 long rawFileSize = OH_ResourceManager_GetRawFileSize(rawFile); 59 ``` 60 616. 根据RawFile实例,使用OH_ResourceManager_SeekRawFile接口指定rawfile偏移量。 62 63 ```c++ 64 int position = OH_ResourceManager_SeekRawFile(rawFile, 10, 0); 65 int position = OH_ResourceManager_SeekRawFile(rawFile, 0 , 1); 66 int position = OH_ResourceManager_SeekRawFile(rawFile, -10, 2); 67 ``` 68 697. 根据RawFile实例,使用OH_ResourceManager_GetRawFileOffset接口获取rawfile偏移量。 70 71 ```c++ 72 long rawFileOffset = OH_ResourceManager_GetRawFileOffset(rawFile) 73 ``` 74 758. 根据RawFile实例,使用OH_ResourceManager_ReadRawFile接口读取rawfile文件内容。 76 77 ```c++ 78 std::unique_ptr<char[]> mediaData = std::make_unique<char[]>(rawFileSize); 79 long rawFileOffset = OH_ResourceManager_ReadRawFile(rawFile, mediaData.get(), rawFileSize); 80 ``` 81 829. 根据RawFile实例,使用OH_ResourceManager_GetRawFileRemainingLength接口读取rawfile文件的剩余长度。 83 84 ```c++ 85 int64_t rawFileRemainingSize = OH_ResourceManager_GetRawFileRemainingLength(rawFile); 86 ``` 87 8810. 根据RawFile实例,使用OH_ResourceManager_CloseRawFile接口释放rawfile文件相关资源。 89 90 ```c++ 91 OH_ResourceManager_CloseRawFile(rawFile); 92 ``` 93 9411. 根据RawDir实例,使用OH_ResourceManager_CloseRawDir接口释放rawfile目录相关资源。 95 96 ```c++ 97 OH_ResourceManager_CloseRawDir(rawDir); 98 ``` 99 10012. 根据RawFile实例,使用OH_ResourceManager_GetRawFileDescriptor接口获取rawfile的RawFileDescriptor。 101 102 ```c++ 103 RawFileDescriptor descriptor; 104 bool result = OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor); 105 ``` 106 10713. 根据RawFileDescriptor实例,使用OH_ResourceManager_ReleaseRawFileDescriptor接口关闭rawfile的fd。 108 109 ```c++ 110 OH_ResourceManager_ReleaseRawFileDescriptor(descriptor); 111 ``` 112 11314. 根据NativeResourceManager实例,使用OH_ResourceManager_ReleaseNativeResourceManager接口释放native resource manager。 114 115 ```c++ 116 OH_ResourceManager_ReleaseNativeResourceManager(nativeResourceManager); 117 ``` 118 119## 开发步骤 120 121 以ArkTS侧获取rawfile文件列表、rawfile文件内容、rawfile描述符{fd, offset, length}三种调用方式为例。 122 123**1. 创建工程** 124 125 126 127**2. 添加依赖** 128 129创建完成后,IDE会在工程生成cpp目录,目录有libentry/index.d.ts、hello.cpp、CMakeLists.txt等文件。 130 1311. 打开src/main/cpp/CMakeLists.txt,在target_link_libraries依赖中添加资源的librawfile.z.so以及日志依赖libhilog_ndk.z.so。 132 133 ```c++ 134 target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so librawfile.z.so) 135 ``` 136 1372. 打开src/main/cpp/types/libentry/index.d.ts文件,此文件声明了应用侧函数getFileList、getRawFileContent、getRawFileDescriptor。 138 139 ```c++ 140 import resourceManager from '@ohos.resourceManager'; 141 export const getFileList: (resmgr: resourceManager.ResourceManager, path: string) => Array<String>; 142 export const getRawFileContent: (resmgr: resourceManager.ResourceManager, path: string) => Uint8Array; 143 export const getRawFileDescriptor: (resmgr: resourceManager.ResourceManager, path: string) => resourceManager.RawFileDescriptor; 144 ``` 145 146**3. 修改源文件** 147 1481. 打开src/main/cpp/hello.cpp文件,文件Init会对当前方法进行初始化映射,这里定义对外接口为getFileList、getRawFileContent、getRawFileDescriptor,映射C++接口分别为GetFileList、GetRawFileContent、GetRawFileDescriptor。 149 150 ```c++ 151 EXTERN_C_START 152 static napi_value Init(napi_env env, napi_value exports) 153 { 154 napi_property_descriptor desc[] = { 155 { "getFileList", nullptr, GetFileList, nullptr, nullptr, nullptr, napi_default, nullptr }, 156 { "getRawFileContent", nullptr, GetRawFileContent, nullptr, nullptr, nullptr, napi_default, nullptr }, 157 { "getRawFileDescriptor", nullptr, GetRawFileDescriptor, nullptr, nullptr, nullptr, napi_default, nullptr } 158 }; 159 160 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 161 return exports; 162 } 163 EXTERN_C_END 164 ``` 165 1662. 把src/main/cpp/hello.cpp文件中,增加对应的三个方法,如下所示 167 168 ```c++ 169 static napi_value GetFileList(napi_env env, napi_callback_info info) 170 static napi_value GetRawFileContent(napi_env env, napi_callback_info info) 171 static napi_value GetRawFileDescriptor(napi_env env, napi_callback_info info) 172 ``` 173 1743. 在hello.cpp文件中获取Js的资源对象,并转为Native的资源对象,即可调用资源的Native接口,获取rawfile列表、rawfile文件内容以及rawfile描述符{fd, offset, length}三种调用方式示例代码如下: 175 176 ```c++ 177 #include <rawfile/raw_file.h> 178 #include <rawfile/raw_dir.h> 179 #include <rawfile/raw_file_manager.h> 180 181 // 示例一:获取rawfile文件列表 GetFileList 182 static napi_value GetFileList(napi_env env, napi_callback_info info) 183 { 184 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "NDKTest Begin"); 185 size_t requireArgc = 3; 186 size_t argc = 2; 187 napi_value argv[2] = { nullptr }; 188 // 获取参数信息 189 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 190 191 // argv[0]即为函数第一个参数Js资源对象,OH_ResourceManager_InitNativeResourceManager转为Native对象。 192 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 193 194 // 获取函数argv[1],此为为rawfile相对路径 195 size_t strSize; 196 char strBuf[256]; 197 napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); 198 std::string dirName(strBuf, strSize); 199 200 // 获取对应的rawDir指针对象 201 RawDir* rawDir = OH_ResourceManager_OpenRawDir(mNativeResMgr, dirName.c_str()); 202 203 // 获取rawDir下文件及文件夹数量 204 int count = OH_ResourceManager_GetRawFileCount(rawDir); 205 206 // 遍历获取文件名称,并保存 207 std::vector<std::string> tempArray; 208 for(int i = 0; i < count; i++) { 209 std::string filename = OH_ResourceManager_GetRawFileName(rawDir, i); 210 tempArray.emplace_back(filename); 211 } 212 213 napi_value fileList; 214 napi_create_array(env, &fileList); 215 for (size_t i = 0; i < tempArray.size(); i++) { 216 napi_value jsString; 217 napi_create_string_utf8(env, tempArray[i].c_str(), NAPI_AUTO_LENGTH, &jsString); 218 napi_set_element(env, fileList, i, jsString); 219 } 220 221 // 关闭打开的指针对象 222 OH_ResourceManager_CloseRawDir(rawDir); 223 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 224 return fileList; 225 } 226 227 // 示例二:获取rawfile文件内容 GetRawFileContent 228 napi_value CreateJsArrayValue(napi_env env, std::unique_ptr<uint8_t[]> &data, long length) 229 { 230 napi_value buffer; 231 napi_status status = napi_create_external_arraybuffer(env, data.get(), length, 232 [](napi_env env, void *data, void *hint) { 233 delete[] static_cast<char*>(data); 234 }, nullptr, &buffer); 235 if (status != napi_ok) { 236 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "Failed to create external array buffer"); 237 return nullptr; 238 } 239 napi_value result = nullptr; 240 status = napi_create_typedarray(env, napi_uint8_array, length, buffer, 0, &result); 241 if (status != napi_ok) { 242 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "Failed to create media typed array"); 243 return nullptr; 244 } 245 data.release(); 246 return result; 247 } 248 static napi_value GetRawFileContent(napi_env env, napi_callback_info info) 249 { 250 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "GetFileContent Begin"); 251 size_t requireArgc = 3; 252 size_t argc = 2; 253 napi_value argv[2] = { nullptr }; 254 // 获取参数信息 255 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 256 257 // argv[0]即为函数第一个参数Js资源对象,OH_ResourceManager_InitNativeResourceManager转为Native对象。 258 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 259 size_t strSize; 260 char strBuf[256]; 261 napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); 262 std::string filename(strBuf, strSize); 263 264 // 获取rawfile指针对象 265 RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str()); 266 if (rawFile != nullptr) { 267 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "OH_ResourceManager_OpenRawFile success"); 268 } 269 // 获取rawfile大小并申请内存 270 long len = OH_ResourceManager_GetRawFileSize(rawFile); 271 std::unique_ptr<uint8_t[]> data= std::make_unique<uint8_t[]>(len); 272 273 // 一次性读取rawfile全部内容 274 int res = OH_ResourceManager_ReadRawFile(rawFile, data.get(), len); 275 276 // 多次部分读取rawfile, 每次读取100 Byte。获取全部内容 277 // long offset = 0; 278 // while (OH_ResourceManager_GetRawFileRemainingLength(rawFile) > 0) { 279 // OH_ResourceManager_ReadRawFile(rawFile, data.get() + offset, 100); 280 // offset += 100; 281 // } 282 283 // 关闭打开的指针对象 284 OH_ResourceManager_CloseRawFile(rawFile); 285 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 286 // 转为js对象 287 return CreateJsArrayValue(env, data, len); 288 } 289 290 // 示例三:获取rawfile文件描述符 GetRawFileDescriptor 291 napi_value createJsFileDescriptor(napi_env env, RawFileDescriptor &descriptor) 292 { 293 napi_value result; 294 napi_status status = napi_create_object(env, &result); 295 if (status != napi_ok) { 296 return result; 297 } 298 299 napi_value fd; 300 status = napi_create_int32(env, descriptor.fd, &fd); 301 if (status != napi_ok) { 302 return result; 303 } 304 status = napi_set_named_property(env, result, "fd", fd); 305 if (status != napi_ok) { 306 return result; 307 } 308 309 napi_value offset; 310 status = napi_create_int64(env, descriptor.start, &offset); 311 if (status != napi_ok) { 312 return result; 313 } 314 status = napi_set_named_property(env, result, "offset", offset); 315 if (status != napi_ok) { 316 return result; 317 } 318 319 napi_value length; 320 status = napi_create_int64(env, descriptor.length, &length); 321 if (status != napi_ok) { 322 return result; 323 } 324 status = napi_set_named_property(env, result, "length", length); 325 if (status != napi_ok) { 326 return result; 327 } 328 return result; 329 } 330 static napi_value GetRawFileDescriptor(napi_env env, napi_callback_info info) 331 { 332 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "NDKTest GetRawFileDescriptor Begin"); 333 size_t requireArgc = 3; 334 size_t argc = 2; 335 napi_value argv[2] = { nullptr }; 336 // 获取参数信息 337 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 338 339 napi_valuetype valueType; 340 napi_typeof(env, argv[0], &valueType); 341 // 获取native的resourceManager对象 342 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 343 size_t strSize; 344 char strBuf[256]; 345 napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); 346 std::string filename(strBuf, strSize); 347 // 获取rawfile指针对象 348 RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str()); 349 if (rawFile != nullptr) { 350 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "OH_ResourceManager_OpenRawFile success"); 351 } 352 // 获取rawfile的描述符RawFileDescriptor {fd, offset, length} 353 RawFileDescriptor descriptor; 354 OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor); 355 // 关闭打开的指针对象 356 OH_ResourceManager_CloseRawFile(rawFile); 357 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 358 // 转为js对象 359 return createJsFileDescriptor(env,descriptor); 360 } 361 ``` 362 363**4. Js侧调用** 364 3651. 打开src\main\ets\pages\index.ets, 导入"libentry.so"; 366 3672. 资源获取包括获取本应用包资源、应用内跨包资源、跨应用包资源。<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)。 368 3693. 调用Native接口getFileList即为src/main/cpp/types/libentry/index.d.ts中声明的接口,传入js的资源对象,以及rawfile文件夹的相对路径。 370 371 获取本应用包资源resourceManager对象的示例如下: 372 373 ```js 374 import hilog from '@ohos.hilog'; 375 import testNapi from 'libentry.so' // 导入so 376 @Entry 377 @Component 378 struct Index { 379 @State message: string = 'Hello World' 380 private resmgr = getContext().resourceManager; // 获取本应用包的资源对象 381 build() { 382 Row() { 383 Column() { 384 Text(this.message) 385 .fontSize(50) 386 .fontWeight(FontWeight.Bold) 387 .onClick(() => { 388 hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); 389 let rawfilelist = testNapi.getFileList(this.resmgr, ""); //传入资源对象,以及访问的rawfile文件夹名称 390 console.log("rawfilelist" + rawfilelist); 391 let rawfileContet = testNapi.getRawFileContent(this.resmgr, "rawfile1.txt"); 392 console.log("rawfileContet" + rawfileContet); 393 let rawfileDescriptor = testNapi.getRawFileDescriptor(this.resmgr, "rawfile1.txt"); 394 console.log("getRawFileDescriptor" + rawfileDescriptor.fd, rawfileDescriptor.offset, rawfileDescriptor.length); 395 }) 396 } 397 .width('100%') 398 } 399 .height('100%') 400 } 401 } 402 ``` 403 404## 相关实例 405 406针对资源管理Rawfile开发,有以下相关实例可供参考: 407 408- [获取Rawfile资源(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Native/NdkRawfile) 409