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