1# Raw File Development 2 3## When to Use 4 5This document describes how to use the native Rawfile APIs to manage raw file directories and files in OpenHarmony. You can use Rawfile APIs to perform operations such as traversing the file list, opening, searching for, reading, and closing raw files. 6 7## Available APIs 8 9| Name | Description | 10| :----------------------------------------------------------- | :--------------------------------------- | 11| NativeResourceManager *OH_ResourceManager_InitNativeResourceManager(napi_env env, napi_value jsResMgr) | Initializes the native resource manager. | 12| RawDir *OH_ResourceManager_OpenRawDir(const NativeResourceManager *mgr, const char *dirName) | Opens a raw file directory. | 13| int OH_ResourceManager_GetRawFileCount(RawDir *rawDir) | Obtains the number of raw files in the specified directory.| 14| const char *OH_ResourceManager_GetRawFileName(RawDir *rawDir, int index) | Obtains the name of a raw file. | 15| RawFile *OH_ResourceManager_OpenRawFile(const NativeResourceManager *mgr, const char *fileName) | Opens a raw file. | 16| long OH_ResourceManager_GetRawFileSize(RawFile *rawFile) | Obtains the size of a raw file. | 17| 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. | 18| long OH_ResourceManager_GetRawFileOffset(const RawFile *rawFile) | Obtains the offset. | 19| int OH_ResourceManager_ReadRawFile(const RawFile *rawFile, void *buf, size_t length) | Reads a raw file. | 20| void OH_ResourceManager_CloseRawFile(RawFile *rawFile) | Closes a raw file to release resources. | 21| void OH_ResourceManager_CloseRawDir(RawDir *rawDir) | Closes a raw file directory to release resources. | 22| bool OH_ResourceManager_GetRawFileDescriptor(const RawFile *rawFile, RawFileDescriptor &descriptor) | Obtains the file descriptor (FD) of a raw file. | 23| bool OH_ResourceManager_ReleaseRawFileDescriptor(const RawFileDescriptor &descriptor) | Releases the FD of a raw file. | 24| void OH_ResourceManager_ReleaseNativeResourceManager(NativeResourceManager *resMgr) | Releases the native resource manager. | 25 26## How to Develop 27 28 The following describes how to obtain the raw file list, raw file content, and raw file descriptor on the JavaScript side as an example. 29 30**1. Create a project.** 31 32![Creating a C++ application](figures/rawfile1.png) 33 34**2. Add dependencies.** 35 36 After a 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**. 37 38 1. Open the **src/main/cpp/CMakeLists.txt** file, and add **librawfile.z.so** and **libhilog_ndk.z.so** to **target_link_libraries**. 39 40 ```c++ 41 target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so librawfile.z.so) 42 ``` 43 44 2. Open the **src/main/cpp/types/libentry/index.d.ts** file, and declare the application functions **getFileList**, **getRawFileContent**, and **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 533. Modify the source file. 54 55 1. Open the **src/main/cpp/hello.cpp** file. During initialization, the file maps the external JavaScript APIs **getFileList**, **getRawFileContent**, and **getRawFileDescriptor** to C++ native APIs **GetFileList**, **GetRawFileContent**, and **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 73 2. Add the three functions to the **src/main/cpp/hello.cpp** file. 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 81 3. Obtain JavaScript 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: 82 83 ```c++ 84 // Example 1: Use GetFileList to obtain the raw file list. 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 // Obtain arguments of the native API. 92 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 93 94 // Obtain argv[0], which specifies conversion of the JavaScript resource object (that is, OH_ResourceManager_InitNativeResourceManager) to a native object. 95 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); 96 97 // Obtain argv[1], which specifies the relative path of the raw file. 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 // Obtain the corresponding rawDir pointer object. 104 RawDir* rawDir = OH_ResourceManager_OpenRawDir(mNativeResMgr, dirName.c_str()); 105 106 // Obtain the number of files and folders in rawDir. 107 int count = OH_ResourceManager_GetRawFileCount(rawDir); 108 109 // Traverse rawDir to obtain the list of file names and save it. 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 // Close the rawDir pointer object. 125 OH_ResourceManager_CloseRawDir(rawDir); 126 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 127 return fileList; 128 } 129 130 // Example 2: Use rawDir pointer object to obtain the content of the raw file. 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 // Obtain parameter information. 158 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 159 160 // Obtain argv[0], which specifies conversion of OH_ResourceManager_InitNativeResourceManager to a native object. 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 // Obtain the raw file pointer object. 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 // Obtain the size of the raw file and apply for memory. 173 long len = OH_ResourceManager_GetRawFileSize(rawFile); 174 std::unique_ptr<uint8_t[]> data= std::make_unique<uint8_t[]>(len); 175 // Read the raw file. 176 int res = OH_ResourceManager_ReadRawFile(rawFile, data.get(), len); 177 // Close the raw file pointer object. 178 OH_ResourceManager_CloseRawFile(rawFile); 179 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 180 // Convert the native object to a JavaScript object. 181 return CreateJsArrayValue(env, data, len); 182 } 183 184 // Example 3: Use GetRawFileDescriptor to obtain the FD of the raw file. 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 // Obtain argument information. 231 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 232 233 napi_valuetype valueType; 234 napi_typeof(env, argv[0], &valueType); 235 // Obtain the native resourceManager object. 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 // Obtain the raw file pointer object. 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 // Obtain the FD of the raw file, that is, RawFileDescriptor {fd, offset, length}. 247 RawFileDescriptor descriptor; 248 OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor); 249 // Close the raw file pointer object. 250 OH_ResourceManager_CloseRawFile(rawFile); 251 OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); 252 // Convert the native object to a JavaScript object. 253 return createJsFileDescriptor(env,descriptor); 254 } 255 ``` 256 257**4. Call APIs on the JavaScript side.** 258 259 1. Open **src\main\ets\pages\index.ets**, and import **libentry.so**. 260 261 2. Obtain the JavaScript resource object, that is, **resourceManager**. 262 263 3. Call **getFileList**, that is, the native API declared in **src/main/cpp/types/libentry/index.d.ts**. When calling the API, pass the JavaScript resource object and the relative path of the raw file. The sample code is as follows: 264 265 ```js 266 import hilog from '@ohos.hilog'; 267 import testNapi from 'libentry.so' // Import the libentry.so file. 268 @Entry 269 @Component 270 struct Index { 271 @State message: string = 'Hello World' 272 private resmgr = getContext().resourceManager; // Obtain the JavaScript resource object. 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, ""); // Pass the JavaScript resource object and the relative path of the raw file. 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## Using C++ Functions 297 2981. Call **OH_ResourceManager_OpenRawDir** to obtain a **RawDir** instance based on the **NativeResourceManager** instance. 299 300 ```c++ 301 RawDir* rawDir = OH_ResourceManager_OpenRawDir(nativeResourceManager, path.c_str()); 302 ``` 303 3042. Call **OH_ResourceManager_GetRawFileCount** to obtain the total number of raw files in the directory based on the **RawDir** instance. 305 306 ```c++ 307 int count = OH_ResourceManager_GetRawFileCount(rawDir); 308 ``` 309 3103. Call **OH_ResourceManager_GetRawFileName** to obtain the name of the raw file with the specified index. 311 312 ```c++ 313 for (int index = 0; index < count; index++) { 314 std::string fileName = OH_ResourceManager_GetRawFileName(rawDir, index); 315 } 316 ``` 317 3184. Call **OH_ResourceManager_OpenRawFile** to obtain a **RawFile** instance with the specified file name. 319 320 ```c++ 321 RawFile* rawFile = OH_ResourceManager_OpenRawFile(nativeResourceManager, fileName.c_str()); 322 ``` 323 3245. Call **OH_ResourceManager_GetRawFileSize** to obtain the size of the raw file. 325 326 ```c++ 327 long rawFileSize = OH_ResourceManager_GetRawFileSize(rawFile); 328 ``` 329 3306. Call **OH_ResourceManager_SeekRawFile** to seek a read/write position in the raw file based on the specified offset. 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. Call **OH_ResourceManager_GetRawFileOffset** to obtain the raw file offset. 339 340 ```c++ 341 long rawFileOffset = OH_ResourceManager_GetRawFileOffset(rawFile) 342 ``` 343 3448. Call **OH_ResourceManager_ReadRawFile** to read the raw file. 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. Call **OH_ResourceManager_CloseRawFile** to close the file to release resources. 352 353 ```c++ 354 OH_ResourceManager_CloseRawFile(rawFile); 355 ``` 356 35710. Call **OH_ResourceManager_CloseRawDir** to close the raw file directory. 358 359 ```c++ 360 OH_ResourceManager_CloseRawDir(rawDir); 361 ``` 362 36311. Call **OH_ResourceManager_GetRawFileDescriptor** to obtain the FD of the raw file. 364 365 ```c++ 366 RawFileDescriptor descriptor; 367 bool result = OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor); 368 ``` 369 37012. Call **OH_ResourceManager_ReleaseRawFileDescriptor** to release the FD of the raw file. 371 372 ```c++ 373 OH_ResourceManager_ReleaseRawFileDescriptor(descriptor); 374 ``` 375 37613. Call **OH_ResourceManager_ReleaseNativeResourceManager** to release the native resource manager. 377 378 ```c++ 379 OH_ResourceManager_ReleaseNativeResourceManager(nativeResourceManager); 380 ``` 381