1# Rawfile开发指导
2
3## 场景介绍
4
5开发者可以通过本指导了解在OpenHarmony应用中,如何使用Native Rawfile接口操作Rawfile目录和文件。功能包括文件列表遍历、文件打开、搜索、读取和关闭Rawfile。
664后缀相关接口属于新增接口,新接口支持打开更大的rawfile文件(超过2G以上建议使用),具体请参考:[Rawfile接口介绍](../reference/apis-localization-kit/rawfile.md)。64相关的开发步骤和非64一致,将非64接口替换为64接口即可,例如:OH_ResourceManager_OpenRawFile替换为OH_ResourceManager_OpenRawFile64。
7
8## 接口说明
9
10| 接口名                                                       | 描述                                     |
11| :----------------------------------------------------------- | :--------------------------------------- |
12| NativeResourceManager *OH_ResourceManager_InitNativeResourceManager(napi_env env, napi_value jsResMgr) | 初始化native resource manager。          |
13| RawDir *OH_ResourceManager_OpenRawDir(const NativeResourceManager *mgr, const char *dirName) | 打开指定rawfile目录。                    |
14| int OH_ResourceManager_GetRawFileCount(RawDir *rawDir)       | 获取指定rawfile目录下的rawfile文件数量。 |
15| const char *OH_ResourceManager_GetRawFileName(RawDir *rawDir, int index) | 获取rawfile名字。                        |
16| RawFile *OH_ResourceManager_OpenRawFile(const NativeResourceManager *mgr, const char *fileName) | 打开指定rawfile文件。                    |
17| long OH_ResourceManager_GetRawFileSize(RawFile *rawFile)     | 获取rawfile文件大小。                    |
18| int OH_ResourceManager_SeekRawFile(const RawFile *rawFile, long offset, int whence) | 指定rawfile内偏移量。                    |
19| long OH_ResourceManager_GetRawFileOffset(const RawFile *rawFile) | 获取rawfile偏移量。                      |
20| int OH_ResourceManager_ReadRawFile(const RawFile *rawFile, void *buf, size_t length) | 读取rawfile文件内容。                    |
21| int64_t OH_ResourceManager_GetRawFileRemainingLength(const RawFile *rawFile) | 获取rawfile文件剩余长度。                    |
22| void OH_ResourceManager_CloseRawFile(RawFile *rawFile)       | 释放rawfile文件相关资源。                |
23| void OH_ResourceManager_CloseRawDir(RawDir *rawDir)          | 释放rawfile目录相关资源。                |
24| bool OH_ResourceManager_GetRawFileDescriptor(const RawFile *rawFile, RawFileDescriptor &descriptor) | 获取rawfile的fd。                        |
25| bool OH_ResourceManager_ReleaseRawFileDescriptor(const RawFileDescriptor &descriptor) | 释放rawfile的fd。                        |
26| void OH_ResourceManager_ReleaseNativeResourceManager(NativeResourceManager *resMgr) | 释放native resource manager相关资源。    |
27| bool OH_ResourceManager_IsRawDir(const NativeResourceManager *mgr, const char *path) | 判断路径是否是rawfile下的目录    |
28
29详细的接口说明请参考[rawfile函数说明](../reference/apis-localization-kit/rawfile.md#函数说明)。
30
31## 开发步骤
32
33   以ArkTS侧获取rawfile文件列表、rawfile文件内容、rawfile描述符{fd, offset, length}三种调用方式为例。
34
35**1. 创建工程**
36
37![创建C++应用](figures/rawfile1.png)
38
39**2. 添加依赖**
40
41创建完成后,DevEco Studio会在工程生成cpp目录,目录有libentry/index.d.tshello.cppCMakeLists.txt等文件。
42
431. 打开src/main/cpp/CMakeLists.txt,在target_link_libraries依赖中添加资源的librawfile.z.so以及日志依赖libhilog_ndk.z.so44
45    ```c++
46    target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so librawfile.z.so)
47    ```
48
492. 打开src/main/cpp/types/libentry/index.d.ts文件,此文件声明了应用侧函数getFileList、getRawFileContent、getRawFileDescriptor。
50
51    ```c++
52    import resourceManager from '@ohos.resourceManager';
53    export const getFileList: (resmgr: resourceManager.ResourceManager, path: string) => Array<String>;
54    export const getRawFileContent: (resmgr: resourceManager.ResourceManager, path: string) => Uint8Array;
55    export const getRawFileDescriptor: (resmgr: resourceManager.ResourceManager, path: string) => resourceManager.RawFileDescriptor;
56    export const isRawDir: (resmgr: resourceManager.ResourceManager, path: string) => Boolean;
57    ```
58
59**3. 修改源文件**
60
611. 打开src/main/cpp/hello.cpp文件,文件Init会对当前方法进行初始化映射,这里定义对外接口为getFileList、getRawFileContent、getRawFileDescriptor,映射C++接口分别为GetFileList、GetRawFileContent、GetRawFileDescriptor。
62
63    ```c++
64    EXTERN_C_START
65    static napi_value Init(napi_env env, napi_value exports)
66    {
67        napi_property_descriptor desc[] = {
68            { "getFileList", nullptr, GetFileList, nullptr, nullptr, nullptr, napi_default, nullptr },
69            { "getRawFileContent", nullptr, GetRawFileContent, nullptr, nullptr, nullptr, napi_default, nullptr },
70            { "getRawFileDescriptor", nullptr, GetRawFileDescriptor, nullptr, nullptr, nullptr, napi_default, nullptr },
71            { "isRawDir", nullptr, IsRawDir, nullptr, nullptr, nullptr, napi_default, nullptr }
72        };
73
74        napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
75        return exports;
76    }
77    EXTERN_C_END
78    ```
79
802. 把src/main/cpp/hello.cpp文件中,增加对应的三个方法,如下所示
81
82    ```c++
83    static napi_value GetFileList(napi_env env, napi_callback_info info)
84    static napi_value GetRawFileContent(napi_env env, napi_callback_info info)
85    static napi_value GetRawFileDescriptor(napi_env env, napi_callback_info info)
86    static napi_value IsRawDir(napi_env env, napi_callback_info info)
87    ```
88
893. 在hello.cpp文件中获取Js的资源对象,并转为Native的资源对象,即可调用资源的Native接口,获取rawfile列表、rawfile文件内容以及rawfile描述符{fd, offset, length}三种调用方式示例代码如下:
90
91    ```c++
92    #include <rawfile/raw_file.h>
93    #include <rawfile/raw_dir.h>
94    #include <rawfile/raw_file_manager.h>
95
96    // 示例一:获取rawfile文件列表 GetFileList
97    static napi_value GetFileList(napi_env env, napi_callback_info info)
98    {
99        OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "NDKTest Begin");
100        size_t requireArgc = 3;
101        size_t argc = 2;
102        napi_value argv[2] = { nullptr };
103        // 获取参数信息
104        napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
105
106        // argv[0]即为函数第一个参数Js资源对象,OH_ResourceManager_InitNativeResourceManager转为Native对象。
107        NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]);
108
109        // 获取函数argv[1],此为为rawfile相对路径
110        size_t strSize;
111        char strBuf[256];
112        napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize);
113        std::string dirName(strBuf, strSize);
114
115        // 获取对应的rawDir指针对象
116        RawDir* rawDir = OH_ResourceManager_OpenRawDir(mNativeResMgr, dirName.c_str());
117
118        // 获取rawDir下文件及文件夹数量
119        int count = OH_ResourceManager_GetRawFileCount(rawDir);
120
121        // 遍历获取文件名称,并保存
122        std::vector<std::string> tempArray;
123        for(int i = 0; i < count; i++) {
124            std::string filename = OH_ResourceManager_GetRawFileName(rawDir, i);
125            tempArray.emplace_back(filename);
126        }
127
128        napi_value fileList;
129        napi_create_array(env, &fileList);
130        for (size_t i = 0; i < tempArray.size(); i++) {
131            napi_value jsString;
132            napi_create_string_utf8(env, tempArray[i].c_str(), NAPI_AUTO_LENGTH, &jsString);
133            napi_set_element(env, fileList, i, jsString);
134        }
135
136        // 关闭打开的指针对象
137        OH_ResourceManager_CloseRawDir(rawDir);
138        OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr);
139        return fileList;
140    }
141
142    // 示例二:获取rawfile文件内容 GetRawFileContent
143    napi_value CreateJsArrayValue(napi_env env, std::unique_ptr<uint8_t[]> &data, long length)
144    {
145        napi_value buffer;
146        napi_status status = napi_create_external_arraybuffer(env, data.get(), length,
147                [](napi_env env, void *data, void *hint) {
148                    delete[] static_cast<char*>(data);
149                }, nullptr, &buffer);
150        if (status != napi_ok) {
151            OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "Failed to create external array buffer");
152            return nullptr;
153        }
154        napi_value result = nullptr;
155        status = napi_create_typedarray(env, napi_uint8_array, length, buffer, 0, &result);
156        if (status != napi_ok) {
157            OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "Failed to create media typed array");
158            return nullptr;
159        }
160        data.release();
161        return result;
162    }
163    static napi_value GetRawFileContent(napi_env env, napi_callback_info info)
164    {
165        OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "GetFileContent Begin");
166        size_t requireArgc = 3;
167        size_t argc = 2;
168        napi_value argv[2] = { nullptr };
169        // 获取参数信息
170        napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
171
172        // argv[0]即为函数第一个参数Js资源对象,OH_ResourceManager_InitNativeResourceManager转为Native对象。
173        NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]);
174        size_t strSize;
175        char strBuf[256];
176        napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize);
177        std::string filename(strBuf, strSize);
178
179        // 获取rawfile指针对象
180        RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str());
181        if (rawFile != nullptr) {
182            OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "OH_ResourceManager_OpenRawFile success");
183        }
184        // 获取rawfile大小并申请内存
185        long len = OH_ResourceManager_GetRawFileSize(rawFile);
186        std::unique_ptr<uint8_t[]> data= std::make_unique<uint8_t[]>(len);
187
188        // 一次性读取rawfile全部内容
189        int res = OH_ResourceManager_ReadRawFile(rawFile, data.get(), len);
190
191        // 多次部分读取rawfile, 每次读取100 Bytes。获取全部内容
192        // long offset = 0;
193        // while (OH_ResourceManager_GetRawFileRemainingLength(rawFile) > 0) {
194        //     OH_ResourceManager_ReadRawFile(rawFile, data.get() + offset, 100);
195        //     offset += 100;
196        // }
197
198        // 关闭打开的指针对象
199        OH_ResourceManager_CloseRawFile(rawFile);
200        OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr);
201        // 转为js对象
202        return CreateJsArrayValue(env, data, len);
203    }
204
205    // 示例三:获取rawfile文件描述符 GetRawFileDescriptor
206    napi_value createJsFileDescriptor(napi_env env, RawFileDescriptor &descriptor)
207    {
208        napi_value result;
209        napi_status status = napi_create_object(env, &result);
210        if (status != napi_ok) {
211            return result;
212        }
213
214        napi_value fd;
215        status = napi_create_int32(env, descriptor.fd, &fd);
216        if (status != napi_ok) {
217            return result;
218        }
219        status = napi_set_named_property(env, result, "fd", fd);
220        if (status != napi_ok) {
221            return result;
222        }
223
224        napi_value offset;
225        status = napi_create_int64(env, descriptor.start, &offset);
226        if (status != napi_ok) {
227            return result;
228        }
229        status = napi_set_named_property(env, result, "offset", offset);
230        if (status != napi_ok) {
231            return result;
232        }
233
234        napi_value length;
235        status = napi_create_int64(env, descriptor.length, &length);
236        if (status != napi_ok) {
237            return result;
238        }
239        status = napi_set_named_property(env, result, "length", length);
240        if (status != napi_ok) {
241            return result;
242        }
243        return result;
244    }
245    static napi_value GetRawFileDescriptor(napi_env env, napi_callback_info info)
246    {
247        OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "NDKTest GetRawFileDescriptor Begin");
248        size_t requireArgc = 3;
249        size_t argc = 2;
250        napi_value argv[2] = { nullptr };
251        // 获取参数信息
252        napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
253
254        napi_valuetype valueType;
255        napi_typeof(env, argv[0], &valueType);
256        // 获取native的resourceManager对象
257        NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]);
258        size_t strSize;
259        char strBuf[256];
260        napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize);
261        std::string filename(strBuf, strSize);
262        // 获取rawfile指针对象
263        RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str());
264        if (rawFile != nullptr) {
265            OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "OH_ResourceManager_OpenRawFile success");
266        }
267        // 获取rawfile的描述符RawFileDescriptor {fd, offset, length}
268        RawFileDescriptor descriptor;
269        OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor);
270        // 关闭打开的指针对象
271        OH_ResourceManager_CloseRawFile(rawFile);
272        OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr);
273        // 转为js对象
274        return createJsFileDescriptor(env,descriptor);
275    }
276    napi_value CreateJsBool(napi_env env, bool &bValue)
277    {
278        napi_value jsValue = nullptr;
279        if (napi_get_boolean(env, bValue, &jsValue) != napi_ok) {
280            return nullptr;
281        }
282        return jsValue;
283    }
284    static napi_value IsRawDir(napi_env env, napi_callback_info info)
285    {
286        OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "NDKTest IsRawDir Begin");
287        size_t requireArgc = 3;
288        size_t argc = 2;
289        napi_value argv[2] = { nullptr };
290        // 获取参数信息
291        napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
292
293        napi_valuetype valueType;
294        napi_typeof(env, argv[0], &valueType);
295        // 获取native的resourceManager对象
296        NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]);
297
298        napi_valuetype valueType1;
299        napi_typeof(env, argv[1], &valueType);
300        if (valueType1 == napi_undefined || valueType1 == napi_null) {
301            bool temp = false;
302            return CreateJsBool(env, temp);
303        }
304        size_t strSize;
305        char strBuf[256];
306        napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize);
307        std::string filename(strBuf, strSize);
308        // 获取rawfile指针对象
309        bool result = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str());
310        OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr);
311        return CreateJsBool(env, result);
312    }
313    ```
314
315**4. Js侧调用**
316
3171. 打开src\main\ets\pages\index.ets, 导入"libentry.so";
318
3192. 资源获取包括获取本应用包资源、应用内跨包资源、跨应用包资源。<br>获取本应用包resourceManager对象,通过.context().resourceManager方法。<br>获取应用内跨包resourceManager对象,通过.context().createModuleContext().resourceManager 方法。<br>获取跨应用包resourceManager对象,通过.context.createModuleContext(bundleName:'bundleName name',moduleName:'module name').resourceManager方法,该方法仅支持系统应用使用。<br>Context的更多使用信息请参考[应用上下文Context](../application-models/application-context-stage.md)。
320
3213. 调用Native接口getFileList即为src/main/cpp/types/libentry/index.d.ts中声明的接口,传入js的资源对象,以及rawfile文件夹的相对路径。
322
323   获取本应用包资源resourceManager对象的示例如下:
324
325    ```js
326    import hilog from '@ohos.hilog';
327    import testNapi from 'libentry.so'  // 导入so
328    @Entry
329    @Component
330    struct Index {
331        @State message: string = 'Hello World'
332        private resmgr = getContext().resourceManager;  // 获取本应用包的资源对象
333        build() {
334            Row() {
335            Column() {
336                Text(this.message)
337                .fontSize(50)
338                .fontWeight(FontWeight.Bold)
339                .onClick(() => {
340                    hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);
341                    let rawfilelist = testNapi.getFileList(this.resmgr, ""); //传入资源对象,以及访问的rawfile文件夹名称
342                    console.log("rawfilelist" + rawfilelist);
343                    let rawfileContet = testNapi.getRawFileContent(this.resmgr, "rawfile1.txt");
344                    console.log("rawfileContet" + rawfileContet);
345                    let rawfileDescriptor = testNapi.getRawFileDescriptor(this.resmgr, "rawfile1.txt");
346                    console.log("getRawFileDescriptor" + rawfileDescriptor.fd, rawfileDescriptor.offset, rawfileDescriptor.length);
347                    let ret = testNapi.isRawDir(this.resmgr, "rawfile1.txt");
348                })
349            }
350            .width('100%')
351            }
352            .height('100%')
353        }
354    }
355    ```
356
357## 相关实例
358
359针对资源管理Rawfile开发,有以下相关实例可供参考:
360
361- [获取Rawfile资源(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Native/NdkRawfile)
362