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   ![Creating a C++ application](figures/rawfile1.png)
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       ```