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 30For details about the APIs, see [Function Description](../reference/apis-localization-kit/rawfile.md#function-description). 31 32## How to Develop 33 34The following describes how to obtain the raw file list, raw file content, and raw file descriptor{fd, offset, length} using ArkTS as an example. 35 361. Create a project. 37 38  39 402. Add dependencies. 41 42 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**. 43 44 1. Open the **src/main/cpp/CMakeLists.txt** file, and add **librawfile.z.so** and **libhilog_ndk.z.so** to **target_link_libraries**. 45 46 ```c++ 47 target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so librawfile.z.so) 48 ``` 49 50 2. Open the **src/main/cpp/types/libentry/index.d.ts** file, and declare the application functions **getFileList**, **getRawFileContent**, and **getRawFileDescriptor**. 51 52 ```c++ 53 import resourceManager from '@ohos.resourceManager'; 54 export const getFileList: (resmgr: resourceManager.ResourceManager, path: string) => Array<String>; 55 export const getRawFileContent: (resmgr: resourceManager.ResourceManager, path: string) => Uint8Array; 56 export const getRawFileDescriptor: (resmgr: resourceManager.ResourceManager, path: string) => resourceManager.RawFileDescriptor; 57 export const isRawDir: (resmgr: resourceManager.ResourceManager, path: string) => Boolean; 58 ``` 59 603. Modify the source file. 61 62 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**. 63 64 ```c++ 65 EXTERN_C_START 66 static napi_value Init(napi_env env, napi_value exports) 67 { 68 napi_property_descriptor desc[] = { 69 { "getFileList", nullptr, GetFileList, nullptr, nullptr, nullptr, napi_default, nullptr }, 70 { "getRawFileContent", nullptr, GetRawFileContent, nullptr, nullptr, nullptr, napi_default, nullptr }, 71 { "getRawFileDescriptor", nullptr, GetRawFileDescriptor, nullptr, nullptr, nullptr, napi_default, nullptr }, 72 { "isRawDir", nullptr, IsRawDir, nullptr, nullptr, nullptr, napi_default, nullptr } 73 }; 74 75 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 76 return exports; 77 } 78 EXTERN_C_END 79 ``` 80 81 2. Add the three C++ native functions to the **src/main/cpp/hello.cpp** file. 82 83 ```c++ 84 static napi_value GetFileList(napi_env env, napi_callback_info info) 85 static napi_value GetRawFileContent(napi_env env, napi_callback_info info) 86 static napi_value GetRawFileDescriptor(napi_env env, napi_callback_info info) 87 static napi_value IsRawDir(napi_env env, napi_callback_info info) 88 ``` 89 90 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: 91 92 ```c++ 93 #include <rawfile/raw_file.h> 94 #include <rawfile/raw_dir.h> 95 #include <rawfile/raw_file_manager.h> 96 97 // Example 1: Use GetFileList to obtain the raw file list. 98 static napi_value GetFileList(napi_env env, napi_callback_info info) 99 { 100 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "NDKTest Begin"); 101 size_t requireArgc = 3; 102 size_t argc = 2; 103 napi_value argv[2] = { nullptr }; 104 // Obtain arguments of the native API. 105 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 106 107 // Obtain argv[0], which specifies conversion of the JS resource object (OH_ResourceManager_InitNativeResourceManager) to a native object. 108 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 109 110 // Obtain argv[1], which specifies the relative path of the raw file. 111 size_t strSize; 112 char strBuf[256]; 113 napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); 114 std::string dirName(strBuf, strSize); 115 116 // Obtain the corresponding rawDir pointer object. 117 RawDir* rawDir = OH_ResourceManager_OpenRawDir(mNativeResMgr, dirName.c_str()); 118 119 // Obtain the number of files and folders in rawDir. 120 int count = OH_ResourceManager_GetRawFileCount(rawDir); 121 122 // Traverse rawDir to obtain the list of file names and save it. 123 std::vector<std::string> tempArray; 124 for(int i = 0; i < count; i++) { 125 std::string filename = OH_ResourceManager_GetRawFileName(rawDir, i); 126 tempArray.emplace_back(filename); 127 } 128 129 napi_value fileList; 130 napi_create_array(env, &fileList); 131 for (size_t i = 0; i < tempArray.size(); i++) { 132 napi_value jsString; 133 napi_create_string_utf8(env, tempArray[i].c_str(), NAPI_AUTO_LENGTH, &jsString); 134 napi_set_element(env, fileList, i, jsString); 135 } 136 137 // Close the rawDir pointer object. 138 OH_ResourceManager_CloseRawDir(rawDir); 139 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 140 return fileList; 141 } 142 143 // Example 2: Use GetRawFileContent to obtain the content of the raw file. 144 napi_value CreateJsArrayValue(napi_env env, std::unique_ptr<uint8_t[]> &data, long length) 145 { 146 napi_value buffer; 147 napi_status status = napi_create_external_arraybuffer(env, data.get(), length, 148 [](napi_env env, void *data, void *hint) { 149 delete[] static_cast<char*>(data); 150 }, nullptr, &buffer); 151 if (status != napi_ok) { 152 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "Failed to create external array buffer"); 153 return nullptr; 154 } 155 napi_value result = nullptr; 156 status = napi_create_typedarray(env, napi_uint8_array, length, buffer, 0, &result); 157 if (status != napi_ok) { 158 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "Failed to create media typed array"); 159 return nullptr; 160 } 161 data.release(); 162 return result; 163 } 164 static napi_value GetRawFileContent(napi_env env, napi_callback_info info) 165 { 166 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "GetFileContent Begin"); 167 size_t requireArgc = 3; 168 size_t argc = 2; 169 napi_value argv[2] = { nullptr }; 170 // Obtain arguments of the native API. 171 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 172 173 // Obtain argv[0], which specifies conversion of the JS resource object (OH_ResourceManager_InitNativeResourceManager) to a native object. 174 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 175 size_t strSize; 176 char strBuf[256]; 177 napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); 178 std::string filename(strBuf, strSize); 179 180 // Obtain the raw file pointer object. 181 RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str()); 182 if (rawFile != nullptr) { 183 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "OH_ResourceManager_OpenRawFile success"); 184 } 185 // Obtain the size of the raw file and apply for memory. 186 long len = OH_ResourceManager_GetRawFileSize(rawFile); 187 std::unique_ptr<uint8_t[]> data= std::make_unique<uint8_t[]>(len); 188 189 // Read all content of the raw file at a time. 190 int res = OH_ResourceManager_ReadRawFile(rawFile, data.get(), len); 191 192 // Read all content of the raw file by multiple times, with 100 bytes per time. 193 // long offset = 0; 194 // while (OH_ResourceManager_GetRawFileRemainingLength(rawFile) > 0) { 195 // OH_ResourceManager_ReadRawFile(rawFile, data.get() + offset, 100); 196 // offset += 100; 197 // } 198 199 // Close the rawFile pointer object. 200 OH_ResourceManager_CloseRawFile(rawFile); 201 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 202 // Convert the native object to a JS object. 203 return CreateJsArrayValue(env, data, len); 204 } 205 206 // Example 3: Use GetRawFileDescriptor to obtain the FD of the raw file. 207 napi_value createJsFileDescriptor(napi_env env, RawFileDescriptor &descriptor) 208 { 209 napi_value result; 210 napi_status status = napi_create_object(env, &result); 211 if (status != napi_ok) { 212 return result; 213 } 214 215 napi_value fd; 216 status = napi_create_int32(env, descriptor.fd, &fd); 217 if (status != napi_ok) { 218 return result; 219 } 220 status = napi_set_named_property(env, result, "fd", fd); 221 if (status != napi_ok) { 222 return result; 223 } 224 225 napi_value offset; 226 status = napi_create_int64(env, descriptor.start, &offset); 227 if (status != napi_ok) { 228 return result; 229 } 230 status = napi_set_named_property(env, result, "offset", offset); 231 if (status != napi_ok) { 232 return result; 233 } 234 235 napi_value length; 236 status = napi_create_int64(env, descriptor.length, &length); 237 if (status != napi_ok) { 238 return result; 239 } 240 status = napi_set_named_property(env, result, "length", length); 241 if (status != napi_ok) { 242 return result; 243 } 244 return result; 245 } 246 static napi_value GetRawFileDescriptor(napi_env env, napi_callback_info info) 247 { 248 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "NDKTest GetRawFileDescriptor Begin"); 249 size_t requireArgc = 3; 250 size_t argc = 2; 251 napi_value argv[2] = { nullptr }; 252 // Obtain arguments of the native API. 253 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 254 255 napi_valuetype valueType; 256 napi_typeof(env, argv[0], &valueType); 257 // Obtain the native resource manager object. 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 // Obtain the raw file pointer object. 264 RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str()); 265 if (rawFile != nullptr) { 266 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "OH_ResourceManager_OpenRawFile success"); 267 } 268 // Obtain the FD of the raw file, that is, RawFileDescriptor {fd, offset, length}. 269 RawFileDescriptor descriptor; 270 OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor); 271 // Close the rawFile pointer object. 272 OH_ResourceManager_CloseRawFile(rawFile); 273 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 274 // Convert the native object to a JS object. 275 return createJsFileDescriptor(env,descriptor); 276 } 277 napi_value CreateJsBool(napi_env env, bool &bValue) 278 { 279 napi_value jsValue = nullptr; 280 if (napi_get_boolean(env, bValue, &jsValue) != napi_ok) { 281 return nullptr; 282 } 283 return jsValue; 284 } 285 static napi_value IsRawDir(napi_env env, napi_callback_info info) 286 { 287 OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "NDKTest IsRawDir Begin"); 288 size_t requireArgc = 3; 289 size_t argc = 2; 290 napi_value argv[2] = { nullptr }; 291 // Obtain arguments of the native API. 292 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 293 294 napi_valuetype valueType; 295 napi_typeof(env, argv[0], &valueType); 296 // Obtain the native resource manager. 297 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 298 299 napi_valuetype valueType1; 300 napi_typeof(env, argv[1], &valueType); 301 if (valueType1 == napi_undefined || valueType1 == napi_null) { 302 bool temp = false; 303 return CreateJsBool(env, temp); 304 } 305 size_t strSize; 306 char strBuf[256]; 307 napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); 308 std::string filename(strBuf, strSize); 309 // Obtain the raw file pointer object. 310 bool result = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str()); 311 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 312 return CreateJsBool(env, result); 313 } 314 ``` 315 3164. Call JS APIs. 317 318 1. Open **src\main\ets\pages\index.ets**, and import **libentry.so**. 319 320 2. Obtain intra-package resources and cross-package resources within an application and cross-application package resources.<br>Call **.context().resourceManager** to obtain a **resourceManager** object for intra-package resources within the application.<br>Call **.context().createModuleContext().resourceManager** to obtain a **resourceManager** object for cross-package resources within the application.<br>Call **.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.<br>For details about **Context**, see [Context (Stage Model)](../application-models/application-context-stage.md). 321 322 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. 323 324 Example: Obtain a **resourceManager** object for intra-package resources within the application. 325 326 ```js 327 import hilog from '@ohos.hilog'; 328 import testNapi from 'libentry.so' // Import the libentry.so file. 329 @Entry 330 @Component 331 struct Index { 332 @State message: string = 'Hello World' 333 private resmgr = getContext().resourceManager; // Obtain the resourceManager object for intra-package resources within the application. 334 build() { 335 Row() { 336 Column() { 337 Text(this.message) 338 .fontSize(50) 339 .fontWeight(FontWeight.Bold) 340 .onClick(() => { 341 hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); 342 let rawfilelist = testNapi.getFileList(this.resmgr, ""); // Pass in the JS resource object and the relative path of the raw file. 343 console.log("rawfilelist" + rawfilelist); 344 let rawfileContet = testNapi.getRawFileContent(this.resmgr, "rawfile1.txt"); 345 console.log("rawfileContet" + rawfileContet); 346 let rawfileDescriptor = testNapi.getRawFileDescriptor(this.resmgr, "rawfile1.txt"); 347 console.log("getRawFileDescriptor" + rawfileDescriptor.fd, rawfileDescriptor.offset, rawfileDescriptor.length); 348 let ret = testNapi.isRawDir(this.resmgr, "rawfile1.txt"); 349 }) 350 } 351 .width('100%') 352 } 353 .height('100%') 354 } 355 } 356 ``` 357