1# Raw File Development 2 3## When to Use 4 5This document describes how to use native RawFile APIs to manage raw file directories and files in OpenHarmony. You can use the APIs to perform operations such as traversing a file list and opening, searching for, reading, and closing raw files. 6 7The APIs ended with **64** are new APIs. These APIs can be used to open raw files larger than 2 GB. For details, see [Rawfile](../reference/apis-localization-kit/rawfile.md). The development procedure is the same for the API ended with **64** and the one does not. For example, you can use **OH_ResourceManager_OpenRawFile** and **OH_ResourceManager_OpenRawFile64** in the same way. 8 9## Available APIs 10 11| API | Description | 12| :----------------------------------------------------------- | :--------------------------------------- | 13| NativeResourceManager *OH_ResourceManager_InitNativeResourceManager(napi_env env, napi_value jsResMgr) | Initializes the native resource manager. | 14| RawDir *OH_ResourceManager_OpenRawDir(const NativeResourceManager *mgr, const char *dirName) | Opens a raw file directory. | 15| int OH_ResourceManager_GetRawFileCount(RawDir *rawDir) | Obtains the number of raw files in a directory.| 16| const char *OH_ResourceManager_GetRawFileName(RawDir *rawDir, int index) | Obtains the name of a raw file. | 17| RawFile *OH_ResourceManager_OpenRawFile(const NativeResourceManager *mgr, const char *fileName) | Opens a raw file. | 18| long OH_ResourceManager_GetRawFileSize(RawFile *rawFile) | Obtains the size of a raw file. | 19| int OH_ResourceManager_SeekRawFile(const RawFile *rawFile, long offset, int whence) | Seeks a read/write position in a raw file based on the specified offset. | 20| long OH_ResourceManager_GetRawFileOffset(const RawFile *rawFile) | Obtains the offset of a raw file. | 21| int OH_ResourceManager_ReadRawFile(const RawFile *rawFile, void *buf, size_t length) | Reads a raw file. | 22| int64_t OH_ResourceManager_GetRawFileRemainingLength(const RawFile *rawFile) | Obtains the remaining length of a raw file. | 23| void OH_ResourceManager_CloseRawFile(RawFile *rawFile) | Closes a raw file to release resources. | 24| void OH_ResourceManager_CloseRawDir(RawDir *rawDir) | Closes a raw file directory to release resources. | 25| bool OH_ResourceManager_GetRawFileDescriptor(const RawFile *rawFile, RawFileDescriptor &descriptor) | Obtains the file descriptor (FD) of a raw file. | 26| bool OH_ResourceManager_ReleaseRawFileDescriptor(const RawFileDescriptor &descriptor) | Releases the FD of a raw file. | 27| void OH_ResourceManager_ReleaseNativeResourceManager(NativeResourceManager *resMgr) | Releases the native resource manager. | 28| bool OH_ResourceManager_IsRawDir(const NativeResourceManager *mgr, const char *path) | Checks whether a path is a subdirectory in the **rawfile** directory. | 29 30 31 32## Using C++ Functions 33 341. Call **OH_ResourceManager_OpenRawDir** to open a raw file directory based on a **NativeResourceManager** instance. 35 36 ```c++ 37 RawDir* rawDir = OH_ResourceManager_OpenRawDir(nativeResourceManager, path.c_str()); 38 ``` 39 402. Call **OH_ResourceManager_GetRawFileCount** to obtain the total number of raw files in the directory. 41 42 ```c++ 43 int count = OH_ResourceManager_GetRawFileCount(rawDir); 44 ``` 45 463. Call **OH_ResourceManager_GetRawFileName** to obtain the name of the raw file with the specified index. 47 48 ```c++ 49 for (int index = 0; index < count; index++) { 50 std::string fileName = OH_ResourceManager_GetRawFileName(rawDir, index); 51 } 52 ``` 53 544. Call **OH_ResourceManager_OpenRawFile** to open a raw file with the specified file name. 55 56 ```c++ 57 RawFile* rawFile = OH_ResourceManager_OpenRawFile(nativeResourceManager, fileName.c_str()); 58 ``` 59 605. Call **OH_ResourceManager_GetRawFileSize** to obtain the size of the raw file. 61 62 ```c++ 63 long rawFileSize = OH_ResourceManager_GetRawFileSize(rawFile); 64 ``` 65 666. Call **OH_ResourceManager_SeekRawFile** to seek a read/write position in the raw file based on the specified offset. 67 68 ```c++ 69 int position = OH_ResourceManager_SeekRawFile(rawFile, 10, 0); 70 int position = OH_ResourceManager_SeekRawFile(rawFile, 0 , 1); 71 int position = OH_ResourceManager_SeekRawFile(rawFile, -10, 2); 72 ``` 73 747. Call **OH_ResourceManager_GetRawFileOffset** to obtain the raw file offset. 75 76 ```c++ 77 long rawFileOffset = OH_ResourceManager_GetRawFileOffset(rawFile) 78 ``` 79 808. Call **OH_ResourceManager_ReadRawFile** to read the raw file. 81 82 ```c++ 83 std::unique_ptr<char[]> mediaData = std::make_unique<char[]>(rawFileSize); 84 long rawFileOffset = OH_ResourceManager_ReadRawFile(rawFile, mediaData.get(), rawFileSize); 85 ``` 86 879. Call **OH_ResourceManager_GetRawFileRemainingLength** to obtain the remaining length of the raw file. 88 89 ```c++ 90 int64_t rawFileRemainingSize = OH_ResourceManager_GetRawFileRemainingLength(rawFile); 91 ``` 92 9310. Call **OH_ResourceManager_CloseRawFile** to close the raw file. 94 95 ```c++ 96 OH_ResourceManager_CloseRawFile(rawFile); 97 ``` 98 9911. Call **OH_ResourceManager_CloseRawDir** to close the raw file directory. 100 101 ```c++ 102 OH_ResourceManager_CloseRawDir(rawDir); 103 ``` 104 10512. Call **OH_ResourceManager_GetRawFileDescriptor** to obtain the FD of the raw file. 106 107 ```c++ 108 RawFileDescriptor descriptor; 109 bool result = OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor); 110 ``` 111 11213. Call **OH_ResourceManager_ReleaseRawFileDescriptor** to release the FD of the raw file. 113 114 ```c++ 115 OH_ResourceManager_ReleaseRawFileDescriptor(descriptor); 116 ``` 117 11814. Call **OH_ResourceManager_ReleaseNativeResourceManager** to release the native resource manager. 119 120 ```c++ 121 OH_ResourceManager_ReleaseNativeResourceManager(nativeResourceManager); 122 ``` 123 12414. Call **OH_ResourceManager_IsRawDir** to check whether the specified path is a raw file directory. 125 126 ```c++ 127 OH_ResourceManager_IsRawDir(nativeResourceManager, path); 128 ``` 129 130## How to Develop 131 132The following describes how to obtain the raw file list, raw file content, and raw file descriptor{fd, offset, length} using ArkTS as an example. 133 1341. Create a project. 135 136  137 1382. Add dependencies. 139 140 After the project is created, the **cpp** directory is created under the project. The directory contains files such as **libentry/index.d.ts**, **hello.cpp**, and **CMakeLists.txt**. 141 142 1. Open the **src/main/cpp/CMakeLists.txt** file, and add **librawfile.z.so** and **libhilog_ndk.z.so** to **target_link_libraries**. 143 144 ```c++ 145 target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so librawfile.z.so) 146 ``` 147 148 2. Open the **src/main/cpp/types/libentry/index.d.ts** file, and declare the application functions **getFileList**, **getRawFileContent**, and **getRawFileDescriptor**. 149 150 ```c++ 151 import resourceManager from '@ohos.resourceManager'; 152 export const getFileList: (resmgr: resourceManager.ResourceManager, path: string) => Array<String>; 153 export const getRawFileContent: (resmgr: resourceManager.ResourceManager, path: string) => Uint8Array; 154 export const getRawFileDescriptor: (resmgr: resourceManager.ResourceManager, path: string) => resourceManager.RawFileDescriptor; 155 export const isRawDir: (resmgr: resourceManager.ResourceManager, path: string) => Boolean; 156 ``` 157 1583. Modify the source file. 159 160 1. Open the **src/main/cpp/hello.cpp** file. During initialization, the file maps the external JavaScript (JS) APIs **getFileList**, **getRawFileContent**, and **getRawFileDescriptor** to C++ native APIs **GetFileList**, **GetRawFileContent**, and **GetRawFileDescriptor**. 161 162 ```c++ 163 EXTERN_C_START 164 static napi_value Init(napi_env env, napi_value exports) 165 { 166 napi_property_descriptor desc[] = { 167 { "getFileList", nullptr, GetFileList, nullptr, nullptr, nullptr, napi_default, nullptr }, 168 { "getRawFileContent", nullptr, GetRawFileContent, nullptr, nullptr, nullptr, napi_default, nullptr }, 169 { "getRawFileDescriptor", nullptr, GetRawFileDescriptor, nullptr, nullptr, nullptr, napi_default, nullptr }, 170 { "isRawDir", nullptr, IsRawDir, nullptr, nullptr, nullptr, napi_default, nullptr } 171 }; 172 173 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 174 return exports; 175 } 176 EXTERN_C_END 177 ``` 178 179 2. Add the three C++ native functions to the **src/main/cpp/hello.cpp** file. 180 181 ```c++ 182 static napi_value GetFileList(napi_env env, napi_callback_info info) 183 static napi_value GetRawFileContent(napi_env env, napi_callback_info info) 184 static napi_value GetRawFileDescriptor(napi_env env, napi_callback_info info) 185 static napi_value IsRawDir(napi_env env, napi_callback_info info) 186 ``` 187 188 3. Obtain JS resource objects from the **hello.cpp** file, and convert them to native resource objects. Then, call the native APIs to obtain the raw file list, raw file content, and raw file descriptor {fd, offset, length}. The sample code is as follows: 189 190 ```c++ 191 #include <rawfile/raw_file.h> 192 #include <rawfile/raw_dir.h> 193 #include <rawfile/raw_file_manager.h> 194 195 // Example 1: Use GetFileList to obtain the raw file list. 196 static napi_value GetFileList(napi_env env, napi_callback_info info) 197 { 198 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "NDKTest Begin"); 199 size_t requireArgc = 3; 200 size_t argc = 2; 201 napi_value argv[2] = { nullptr }; 202 // Obtain arguments of the native API. 203 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 204 205 // Obtain argv[0], which specifies conversion of the JS resource object (OH_ResourceManager_InitNativeResourceManager) to a native object. 206 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 207 208 // Obtain argv[1], which specifies the relative path of the raw file. 209 size_t strSize; 210 char strBuf[256]; 211 napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); 212 std::string dirName(strBuf, strSize); 213 214 // Obtain the corresponding rawDir pointer object. 215 RawDir* rawDir = OH_ResourceManager_OpenRawDir(mNativeResMgr, dirName.c_str()); 216 217 // Obtain the number of files and folders in rawDir. 218 int count = OH_ResourceManager_GetRawFileCount(rawDir); 219 220 // Traverse rawDir to obtain the list of file names and save it. 221 std::vector<std::string> tempArray; 222 for(int i = 0; i < count; i++) { 223 std::string filename = OH_ResourceManager_GetRawFileName(rawDir, i); 224 tempArray.emplace_back(filename); 225 } 226 227 napi_value fileList; 228 napi_create_array(env, &fileList); 229 for (size_t i = 0; i < tempArray.size(); i++) { 230 napi_value jsString; 231 napi_create_string_utf8(env, tempArray[i].c_str(), NAPI_AUTO_LENGTH, &jsString); 232 napi_set_element(env, fileList, i, jsString); 233 } 234 235 // Close the rawDir pointer object. 236 OH_ResourceManager_CloseRawDir(rawDir); 237 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 238 return fileList; 239 } 240 241 // Example 2: Use GetRawFileContent to obtain the content of the raw file. 242 napi_value CreateJsArrayValue(napi_env env, std::unique_ptr<uint8_t[]> &data, long length) 243 { 244 napi_value buffer; 245 napi_status status = napi_create_external_arraybuffer(env, data.get(), length, 246 [](napi_env env, void *data, void *hint) { 247 delete[] static_cast<char*>(data); 248 }, nullptr, &buffer); 249 if (status != napi_ok) { 250 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "Failed to create external array buffer"); 251 return nullptr; 252 } 253 napi_value result = nullptr; 254 status = napi_create_typedarray(env, napi_uint8_array, length, buffer, 0, &result); 255 if (status != napi_ok) { 256 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "Failed to create media typed array"); 257 return nullptr; 258 } 259 data.release(); 260 return result; 261 } 262 static napi_value GetRawFileContent(napi_env env, napi_callback_info info) 263 { 264 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "GetFileContent Begin"); 265 size_t requireArgc = 3; 266 size_t argc = 2; 267 napi_value argv[2] = { nullptr }; 268 // Obtain arguments of the native API. 269 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 270 271 // Obtain argv[0], which specifies conversion of the JS resource object (OH_ResourceManager_InitNativeResourceManager) to a native object. 272 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 273 size_t strSize; 274 char strBuf[256]; 275 napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); 276 std::string filename(strBuf, strSize); 277 278 // Obtain the raw file pointer object. 279 RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str()); 280 if (rawFile != nullptr) { 281 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "OH_ResourceManager_OpenRawFile success"); 282 } 283 // Obtain the size of the raw file and apply for memory. 284 long len = OH_ResourceManager_GetRawFileSize(rawFile); 285 std::unique_ptr<uint8_t[]> data= std::make_unique<uint8_t[]>(len); 286 287 // Read all content of the raw file at a time. 288 int res = OH_ResourceManager_ReadRawFile(rawFile, data.get(), len); 289 290 // Read all content of the raw file by multiple times, with 100 bytes per time. 291 // long offset = 0; 292 // while (OH_ResourceManager_GetRawFileRemainingLength(rawFile) > 0) { 293 // OH_ResourceManager_ReadRawFile(rawFile, data.get() + offset, 100); 294 // offset += 100; 295 // } 296 297 // Close the raw file pointer object. 298 OH_ResourceManager_CloseRawFile(rawFile); 299 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 300 // Convert the native object to a JS object. 301 return CreateJsArrayValue(env, data, len); 302 } 303 304 // Example 3: Use GetRawFileDescriptor to obtain the FD of the raw file. 305 napi_value createJsFileDescriptor(napi_env env, RawFileDescriptor &descriptor) 306 { 307 napi_value result; 308 napi_status status = napi_create_object(env, &result); 309 if (status != napi_ok) { 310 return result; 311 } 312 313 napi_value fd; 314 status = napi_create_int32(env, descriptor.fd, &fd); 315 if (status != napi_ok) { 316 return result; 317 } 318 status = napi_set_named_property(env, result, "fd", fd); 319 if (status != napi_ok) { 320 return result; 321 } 322 323 napi_value offset; 324 status = napi_create_int64(env, descriptor.start, &offset); 325 if (status != napi_ok) { 326 return result; 327 } 328 status = napi_set_named_property(env, result, "offset", offset); 329 if (status != napi_ok) { 330 return result; 331 } 332 333 napi_value length; 334 status = napi_create_int64(env, descriptor.length, &length); 335 if (status != napi_ok) { 336 return result; 337 } 338 status = napi_set_named_property(env, result, "length", length); 339 if (status != napi_ok) { 340 return result; 341 } 342 return result; 343 } 344 static napi_value GetRawFileDescriptor(napi_env env, napi_callback_info info) 345 { 346 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "NDKTest GetRawFileDescriptor Begin"); 347 size_t requireArgc = 3; 348 size_t argc = 2; 349 napi_value argv[2] = { nullptr }; 350 // Obtain arguments of the native API. 351 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 352 353 napi_valuetype valueType; 354 napi_typeof(env, argv[0], &valueType); 355 // Obtain the native resourceManager object. 356 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 357 size_t strSize; 358 char strBuf[256]; 359 napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); 360 std::string filename(strBuf, strSize); 361 // Obtain the raw file pointer object. 362 RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str()); 363 if (rawFile != nullptr) { 364 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "OH_ResourceManager_OpenRawFile success"); 365 } 366 // Obtain the FD of the raw file, that is, RawFileDescriptor {fd, offset, length}. 367 RawFileDescriptor descriptor; 368 OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor); 369 // Close the raw file pointer object. 370 OH_ResourceManager_CloseRawFile(rawFile); 371 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 372 // Convert the native object to a JS object. 373 return createJsFileDescriptor(env,descriptor); 374 } 375 napi_value CreateJsBool(napi_env env, bool &bValue) 376 { 377 napi_value jsValue = nullptr; 378 if (napi_get_boolean(env, bValue, &jsValue) != napi_ok) { 379 return nullptr; 380 } 381 return jsValue; 382 } 383 static napi_value IsRawDir(napi_env env, napi_callback_info info) 384 { 385 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "NDKTest IsRawDir Begin"); 386 size_t requireArgc = 3; 387 size_t argc = 2; 388 napi_value argv[2] = { nullptr }; 389 // Obtain arguments of the native API. 390 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 391 392 napi_valuetype valueType; 393 napi_typeof(env, argv[0], &valueType); 394 // Obtain the native resource manager. 395 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 396 397 napi_valuetype valueType1; 398 napi_typeof(env, argv[1], &valueType); 399 if (valueType1 == napi_undefined || valueType1 == napi_null) { 400 bool temp = false; 401 return CreateJsBool(env, temp); 402 } 403 size_t strSize; 404 char strBuf[256]; 405 napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); 406 std::string filename(strBuf, strSize); 407 // Obtain the raw file pointer object. 408 bool result = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str()); 409 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 410 return CreateJsBool(env, result); 411 } 412 ``` 413 4144. Call JS APIs. 415 416 1. Open **src\main\ets\pages\index.ets**, and import **libentry.so**. 417 418 2. Obtain intra-package resources and cross-package resources within an application and cross-application package resources. 419 420 Use **.context().resourceManager** to obtain a **resourceManager** object for intra-package resources within the application. 421 422 Use **.context().createModuleContext().resourceManager** to obtain a **resourceManager** object for cross-package resources within the application. 423 424 Use **.context.createModuleContext(bundleName:'bundleName name',moduleName:'module name').resourceManager** to obtain a **resourceManager** object for cross-application package resources. This API can be used only by system applications. 425 426 For details about **Context**, see [Context (Stage Model)](../application-models/application-context-stage.md). 427 428 3. Call **getFileList**, that is, the native API declared in **src/main/cpp/types/libentry/index.d.ts**. When calling the API, pass in the JS resource object and the relative path of the raw file. 429 430 Example: Obtain a **resourceManager** object for intra-package resources within the application. 431 432 ```js 433 import hilog from '@ohos.hilog'; 434 import testNapi from 'libentry.so' // Import the libentry.so file. 435 @Entry 436 @Component 437 struct Index { 438 @State message: string = 'Hello World' 439 private resmgr = getContext().resourceManager; // Obtain the resourceManager object for intra-package resources within the application. 440 build() { 441 Row() { 442 Column() { 443 Text(this.message) 444 .fontSize(50) 445 .fontWeight(FontWeight.Bold) 446 .onClick(() => { 447 hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); 448 let rawfilelist = testNapi.getFileList(this.resmgr, ""); // Pass in the JS resource object and the relative path of the raw file. 449 console.log("rawfilelist" + rawfilelist); 450 let rawfileContet = testNapi.getRawFileContent(this.resmgr, "rawfile1.txt"); 451 console.log("rawfileContet" + rawfileContet); 452 let rawfileDescriptor = testNapi.getRawFileDescriptor(this.resmgr, "rawfile1.txt"); 453 console.log("getRawFileDescriptor" + rawfileDescriptor.fd, rawfileDescriptor.offset, rawfileDescriptor.length); 454 let ret = testNapi.isRawDir(this.resmgr, "rawfile1.txt"); 455 }) 456 } 457 .width('100%') 458 } 459 .height('100%') 460 } 461 } 462 ```