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