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