• 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| void OH_ResourceManager_CloseRawFile(RawFile *rawFile)       | 释放rawfile文件相关资源。                |
21| void OH_ResourceManager_CloseRawDir(RawDir *rawDir)          | 释放rawfile目录相关资源。                |
22| bool OH_ResourceManager_GetRawFileDescriptor(const RawFile *rawFile, RawFileDescriptor &descriptor) | 获取rawfile的fd。                        |
23| bool OH_ResourceManager_ReleaseRawFileDescriptor(const RawFileDescriptor &descriptor) | 释放rawfile的fd。                        |
24| void OH_ResourceManager_ReleaseNativeResourceManager(NativeResourceManager *resMgr) | 释放native resource manager相关资源。    |
25
26## 开发步骤
27
28   以Js侧获取rawfile文件列表、rawfile文件内容、rawfile描述符{fd, offset, length}三种调用方式为例。
29
30**1. 创建工程**
31
32![创建C++应用](figures/rawfile1.png)
33
34**2. 添加依赖**
35
36创建完成后,IDE会在工程生成cpp目录,目录有libentry/index.d.tshello.cppCMakeLists.txt等文件。
37
381. 打开src/main/cpp/CMakeLists.txt,在target_link_libraries依赖中添加资源的librawfile.z.so以及日志依赖libhilog_ndk.z.so
39
40    ```c++
41    target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so librawfile.z.so)
42    ```
43
442. 打开src/main/cpp/types/libentry/index.d.ts文件,此文件声明了应用侧函数getFileList、getRawFileContent、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
53**3. 修改源文件**
54
551. 打开src/main/cpp/hello.cpp文件,文件Init会对当前方法进行初始化映射,这里定义对外接口为getFileList、getRawFileContent、getRawFileDescriptor,映射C++接口分别为GetFileList、GetRawFileContent、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
732. 把src/main/cpp/hello.cpp文件中,增加对应的三个方法,如下所示
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
813. 在hello.cpp文件中获取Js的资源对象,并转为Native的资源对象,即可调用资源的Native接口,获取rawfile列表、rawfile文件内容以及rawfile描述符{fd, offset, length}三种调用方式示例代码如下:
82
83    ```c++
84    // 示例一:获取rawfile文件列表 GetFileList
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        // 获取参数信息
92        napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
93
94        // argv[0]即为函数第一个参数Js资源对象,OH_ResourceManager_InitNativeResourceManager转为Native对象。
95        NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]);
96
97        // 获取函数argv[1],此为为rawfile相对路径
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        // 获取对应的rawDir指针对象
104        RawDir* rawDir = OH_ResourceManager_OpenRawDir(mNativeResMgr, dirName.c_str());
105
106        // 获取rawDir下文件及文件夹数量
107        int count = OH_ResourceManager_GetRawFileCount(rawDir);
108
109        // 遍历获取文件名称,并保存
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        // 关闭打开的指针对象
125        OH_ResourceManager_CloseRawDir(rawDir);
126        OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr);
127        return fileList;
128    }
129
130    // 示例二:获取rawfile文件内容 GetRawFileContent
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        // 获取参数信息
158        napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
159
160        // argv[0]即为函数第一个参数Js资源对象,OH_ResourceManager_InitNativeResourceManager转为Native对象。
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        // 获取rawfile指针对象
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        // 获取rawfile大小并申请内存
173        long len = OH_ResourceManager_GetRawFileSize(rawFile);
174        std::unique_ptr<uint8_t[]> data= std::make_unique<uint8_t[]>(len);
175        // 读取rawfile
176        int res = OH_ResourceManager_ReadRawFile(rawFile, data.get(), len);
177        // 关闭打开的指针对象
178        OH_ResourceManager_CloseRawFile(rawFile);
179        OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr);
180        // 转为js对象
181        return CreateJsArrayValue(env, data, len);
182    }
183
184    // 示例三:获取rawfile文件描述符 GetRawFileDescriptor
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        // 获取参数信息
231        napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
232
233        napi_valuetype valueType;
234        napi_typeof(env, argv[0], &valueType);
235        // 获取native的resourceManager对象
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        // 获取rawfile指针对象
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        // 获取rawfile的描述符RawFileDescriptor {fd, offset, length}
247        RawFileDescriptor descriptor;
248        OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor);
249        // 关闭打开的指针对象
250        OH_ResourceManager_CloseRawFile(rawFile);
251        OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr);
252        // 转为js对象
253        return createJsFileDescriptor(env,descriptor);
254    }
255    ```
256
257**4. Js侧调用**
258
2591. 打开src\main\ets\pages\index.ets, 导入"libentry.so";
260
2612. 获取当前js的resourceManager对象;
262
2633. 调用Native接口getFileList即为src/main/cpp/types/libentry/index.d.ts中声明的接口,传入js的资源对象,以及rawfile文件夹的相对路径。示例如下:
264
265    ```js
266    import hilog from '@ohos.hilog';
267    import testNapi from 'libentry.so'  // 导入so
268    @Entry
269    @Component
270    struct Index {
271        @State message: string = 'Hello World'
272        private resmgr = getContext().resourceManager;  // 获取js的资源对象
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, ""); //传入资源对象,以及访问的rawfile文件夹名称
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## 函数介绍
297
2981. 根据NativeResourceManager实例,使用OH_ResourceManager_OpenRawDir接口获取RawDir实例。
299
300    ```c++
301    RawDir* rawDir = OH_ResourceManager_OpenRawDir(nativeResourceManager, path.c_str());
302    ```
303
3042. 根据RawDir实例,使用OH_ResourceManager_GetRawFileCount接口获取对应目录下的rawfile文件总数 。
305
306    ```c++
307    int count = OH_ResourceManager_GetRawFileCount(rawDir);
308    ```
309
3103. 根据RawDir实例,使用OH_ResourceManager_GetRawFileName接口获取目录下对应index的rawfile文件名。
311
312    ```c++
313    for (int index = 0; index < count; index++) {
314        std::string fileName = OH_ResourceManager_GetRawFileName(rawDir, index);
315    }
316    ```
317
3184. 根据NativeResourceManager实例,使用OH_ResourceManager_OpenRawFile接口获取指定文件名的RawFile实例
319
320    ```c++
321    RawFile* rawFile = OH_ResourceManager_OpenRawFile(nativeResourceManager, fileName.c_str());
322    ```
323
3245. 根据RawFile实例,使用OH_ResourceManager_GetRawFileSize接口获取对应rawfile文件大小。
325
326    ```c++
327    long rawFileSize = OH_ResourceManager_GetRawFileSize(rawFile);
328    ```
329
3306. 根据RawFile实例,使用OH_ResourceManager_SeekRawFile接口指定rawfile偏移量。
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. 根据RawFile实例,使用OH_ResourceManager_GetRawFileOffset接口获取rawfile偏移量。
339
340    ```c++
341    long rawFileOffset = OH_ResourceManager_GetRawFileOffset(rawFile)
342    ```
343
3448. 根据RawFile实例,使用OH_ResourceManager_ReadRawFile接口读取rawfile文件内容。
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. 根据RawFile实例,使用OH_ResourceManager_CloseRawFile接口释放rawfile文件相关资源。
352
353    ```c++
354    OH_ResourceManager_CloseRawFile(rawFile);
355    ```
356
35710. 根据RawDir实例,使用OH_ResourceManager_CloseRawDir接口释放rawfile目录相关资源。
358
359    ```c++
360    OH_ResourceManager_CloseRawDir(rawDir);
361    ```
362
36311. 根据RawFile实例,使用OH_ResourceManager_GetRawFileDescriptor接口获取rawfile的RawFileDescriptor。
364
365    ```c++
366    RawFileDescriptor descriptor;
367    bool result = OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor);
368    ```
369
37012. 根据RawFileDescriptor实例,使用OH_ResourceManager_ReleaseRawFileDescriptor接口关闭rawfile的fd。
371
372    ```c++
373    OH_ResourceManager_ReleaseRawFileDescriptor(descriptor);
374    ```
375
37613. 根据NativeResourceManager实例,使用OH_ResourceManager_ReleaseNativeResourceManager接口释放native resource manager。
377
378    ```c++
379    OH_ResourceManager_ReleaseNativeResourceManager(nativeResourceManager);
380    ```
381
382