写点什么

Native Rawfile 开发指导

  • 2023-12-11
    北京
  • 本文字数:6565 字

    阅读完需:约 22 分钟

Native Rawfile开发指导

场景介绍

开发者可以通过本指导了解在 HarmonyOS 应用中,如何使用 Native Rawfile 接口操作 Rawfile 目录和文件。功能包括遍历、打开、搜索、读取和关闭 Rawfile。

接口说明




开发步骤

以 Js 侧获取 rawfile 文件列表、rawfile 文件内容、rawfile 描述符{fd, offset, length}三种调用方式为例。

1. 创建工程



2. 添加依赖

创建完成后,IDE 会在工程生成 cpp 目录,目录有 libentry/index.d.ts、hello.cpp、CMakeLists.txt 等文件。

1.  打开 src/main/cpp/CMakeLists.txt,在 target_link_libraries 依赖中添加资源的 librawfile.z.so 以及日志依赖 libhilog_ndk.z.so。


target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so librawfile.z.so)
复制代码


2.  打开 src/main/cpp/types/libentry/index.d.ts 文件,此文件声明了应用侧函数 getFileList、getRawFileContent、getRawFileDescriptor。


import resourceManager from '@ohos.resourceManager';export const getFileList: (resmgr: resourceManager.ResourceManager, path: string) => Array<String>;export const getRawFileContent: (resmgr: resourceManager.ResourceManager, path: string) => Uint8Array;export const getRawFileDescriptor: (resmgr: resourceManager.ResourceManager, path: string) => resourceManager.RawFileDescriptor; 
复制代码


3. 修改源文件

1.  打开 src/main/cpp/hello.cpp 文件,文件 Init 会对当前方法进行初始化映射,这里定义对外接口为 getFileList、getRawFileContent、getRawFileDescriptor,映射 C++接口分别为 GetFileList、GetRawFileContent、GetRawFileDescriptor。


EXTERN_C_STARTstatic napi_value Init(napi_env env, napi_value exports){        napi_property_descriptor desc[] = {                { "getFileList", nullptr, GetFileList, nullptr, nullptr, nullptr, napi_default, nullptr },        { "getRawFileContent", nullptr, GetRawFileContent, nullptr, nullptr, nullptr, napi_default, nullptr },        { "getRawFileDescriptor", nullptr, GetRawFileDescriptor, nullptr, nullptr, nullptr, napi_default, nullptr }    };     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);    return exports;}EXTERN_C_END
复制代码


2.  把 src/main/cpp/hello.cpp 文件中,增加对应的三个方法,如下所示


static napi_value GetFileList(napi_env env, napi_callback_info info)static napi_value GetRawFileContent(napi_env env, napi_callback_info info)static napi_value GetRawFileDescriptor(napi_env env, napi_callback_info info)
复制代码


3.  hello.cpp 文件中获取 Js 的资源对象,并转为 Native 的资源对象,即可调用资源的 Native 接口,获取 rawfile 列表、rawfile 文件内容以及 rawfile 描述符{fd, offset, length}三种调用方式示例代码如下:

#include <rawfile/raw_file.h>#include <rawfile/raw_dir.h>#include <rawfile/raw_file_manager.h>
// 示例一:获取rawfile文件列表 GetFileListstatic napi_value GetFileList(napi_env env, napi_callback_info info){ OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "NDKTest Begin"); size_t requireArgc = 3; size_t argc = 2; napi_value argv[2] = { nullptr }; // 获取参数信息 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); // argv[0]即为函数第一个参数Js资源对象,OH_ResourceManager_InitNativeResourceManager转为Native对象。 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]);
// 获取函数argv[1],此为为rawfile相对路径 size_t strSize; char strBuf[256]; napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); std::string dirName(strBuf, strSize);
// 获取对应的rawDir指针对象 RawDir* rawDir = OH_ResourceManager_OpenRawDir(mNativeResMgr, dirName.c_str());
// 获取rawDir下文件及文件夹数量 int count = OH_ResourceManager_GetRawFileCount(rawDir);
// 遍历获取文件名称,并保存 std::vector<std::string> tempArray; for(int i = 0; i < count; i++) { std::string filename = OH_ResourceManager_GetRawFileName(rawDir, i); tempArray.emplace_back(filename); }
napi_value fileList; napi_create_array(env, &fileList); for (size_t i = 0; i < tempArray.size(); i++) { napi_value jsString; napi_create_string_utf8(env, tempArray[i].c_str(), NAPI_AUTO_LENGTH, &jsString); napi_set_element(env, fileList, i, jsString); }
// 关闭打开的指针对象 OH_ResourceManager_CloseRawDir(rawDir); OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); return fileList;}
// 示例二:获取rawfile文件内容 GetRawFileContentnapi_value CreateJsArrayValue(napi_env env, std::unique_ptr<uint8_t[]> &data, long length){ napi_value buffer; napi_status status = napi_create_external_arraybuffer(env, data.get(), length, [](napi_env env, void *data, void *hint) { delete[] static_cast<char*>(data); }, nullptr, &buffer); if (status != napi_ok) { OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "Failed to create external array buffer"); return nullptr; } napi_value result = nullptr; status = napi_create_typedarray(env, napi_uint8_array, length, buffer, 0, &result); if (status != napi_ok) { OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "Failed to create media typed array"); return nullptr; } data.release(); return result;}
static napi_value GetRawFileContent(napi_env env, napi_callback_info info){ OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "GetFileContent Begin"); size_t requireArgc = 3; size_t argc = 2; napi_value argv[2] = { nullptr }; // 获取参数信息 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
// argv[0]即为函数第一个参数Js资源对象,OH_ResourceManager_InitNativeResourceManager转为Native对象。 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); size_t strSize; char strBuf[256]; napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); std::string filename(strBuf, strSize); // 获取rawfile指针对象 RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str()); if (rawFile != nullptr) { OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "OH_ResourceManager_OpenRawFile success"); } // 获取rawfile大小并申请内存 long len = OH_ResourceManager_GetRawFileSize(rawFile); std::unique_ptr<uint8_t[]> data= std::make_unique<uint8_t[]>(len); // 读取rawfile int res = OH_ResourceManager_ReadRawFile(rawFile, data.get(), len); // 关闭打开的指针对象 OH_ResourceManager_CloseRawFile(rawFile); OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); // 转为js对象 return CreateJsArrayValue(env, data, len);}
// 示例三:获取rawfile文件描述符 GetRawFileDescriptornapi_value createJsFileDescriptor(napi_env env, RawFileDescriptor &descriptor){ napi_value result; napi_status status = napi_create_object(env, &result); if (status != napi_ok) { return result; } napi_value fd; status = napi_create_int32(env, descriptor.fd, &fd); if (status != napi_ok) { return result; } status = napi_set_named_property(env, result, "fd", fd); if (status != napi_ok) { return result; } napi_value offset; status = napi_create_int64(env, descriptor.start, &offset); if (status != napi_ok) { return result; } status = napi_set_named_property(env, result, "offset", offset); if (status != napi_ok) { return result; }
napi_value length; status = napi_create_int64(env, descriptor.length, &length); if (status != napi_ok) { return result; } status = napi_set_named_property(env, result, "length", length); if (status != napi_ok) { return result; } return result;}
static napi_value GetRawFileDescriptor(napi_env env, napi_callback_info info){ OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "NDKTest GetRawFileDescriptor Begin"); size_t requireArgc = 3; size_t argc = 2; napi_value argv[2] = { nullptr }; // 获取参数信息 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
napi_valuetype valueType; napi_typeof(env, argv[0], &valueType); // 获取native的resourceManager对象 NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); size_t strSize; char strBuf[256]; napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize); std::string filename(strBuf, strSize); // 获取rawfile指针对象 RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, filename.c_str()); if (rawFile != nullptr) { OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "OH_ResourceManager_OpenRawFile success"); } // 获取rawfile的描述符RawFileDescriptor {fd, offset, length} RawFileDescriptor descriptor; OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor); // 关闭打开的指针对象 OH_ResourceManager_CloseRawFile(rawFile); OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); // 转为js对象 return createJsFileDescriptor(env,descriptor);}

复制代码

4.  Js 侧调用

a.  打开 src\main\ets\pages\index.ets, 导入"libentry.so";

b.  获取当前 js 的 resourceManager 对象;

c.  调用 Native 接口 getFileList 即为 src/main/cpp/types/libentry/index.d.ts 中声明的接口,传入 js 的资源对象,以及 rawfile 文件夹的相对路径。示例如下:


import hilog from '@ohos.hilog';import testNapi from 'libentry.so'  // 导入so@Entry@Componentstruct Index {    @State message: string = 'Hello World'    private resmgr = getContext().resourceManager;  // 获取js的资源对象    build() {        Row() {        Column() {            Text(this.message)            .fontSize(50)            .fontWeight(FontWeight.Bold)            .onClick(() => {                hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO);                let rawfilelist = testNapi.getFileList(this.resmgr, ""); //传入资源对象,以及访问的rawfile文件夹名称                console.log("rawfilelist" + rawfilelist);                let rawfileContet = testNapi.getRawFileContent(this.resmgr, "rawfile1.txt");                console.log("rawfileContet" + rawfileContet);                let rawfileDescriptor = testNapi.getRawFileDescriptor(this.resmgr, "rawfile1.txt");                console.log("getRawFileDescriptor" + rawfileDescriptor.fd, rawfileDescriptor.offset, rawfileDescriptor.length);            })        }        .width('100%')        }        .height('100%')    }}

复制代码


函数介绍

1.  根据 NativeResourceManager 实例,使用 OH_ResourceManager_OpenRawDir 接口获取 RawDir 实例。


RawDir* rawDir = OH_ResourceManager_OpenRawDir(nativeResourceManager, path.c_str());
复制代码


2.  根据 RawDir 实例,使用 OH_ResourceManager_GetRawFileCount 接口获取对应目录下的 rawfile 文件总数 。


int count = OH_ResourceManager_GetRawFileCount(rawDir);
复制代码


3.  根据 RawDir 实例,使用 OH_ResourceManager_GetRawFileName 接口获取目录下对应 index 的 rawfile 文件名


for (int index = 0; index < count; index++) {    std::string fileName = OH_ResourceManager_GetRawFileName(rawDir, index);}
复制代码


4.  根据 NativeResourceManager 实例,使用 OH_ResourceManager_OpenRawFile 接口获取指定文件名的 RawFile 实例。


RawFile* rawFile = OH_ResourceManager_OpenRawFile(nativeResourceManager, fileName.c_str());
复制代码


5.  根据 RawFile 实例,使用 OH_ResourceManager_GetRawFileSize 接口获取对应 rawfile 文件大小。


long rawFileSize = OH_ResourceManager_GetRawFileSize(rawFile);
复制代码


6.  根据 RawFile 实例,使用 OH_ResourceManager_SeekRawFile 接口指定 rawfile 偏移量。


int position = OH_ResourceManager_SeekRawFile(rawFile, 10, 0);int position = OH_ResourceManager_SeekRawFile(rawFile, 0 , 1);int position = OH_ResourceManager_SeekRawFile(rawFile, -10, 2);
复制代码


7.  根据 RawFile 实例,使用 OH_ResourceManager_GetRawFileOffset 接口获取 rawfile 偏移量。


long rawFileOffset = OH_ResourceManager_GetRawFileOffset(rawFile);
复制代码


8.  根据 RawFile 实例,使用 OH_ResourceManager_ReadRawFile 接口读取 rawfile 文件内容。


std::unique_ptr<char[]> mediaData = std::make_unique<char[]>(rawFileSize);long rawFileOffset = OH_ResourceManager_ReadRawFile(rawFile, mediaData.get(), rawFileSize);
复制代码


9.  根据 RawFile 实例,使用 OH_ResourceManager_CloseRawFile 接口释放 rawfile 文件相关资源。


OH_ResourceManager_CloseRawFile(rawFile);
复制代码


10.  根据 RawDir 实例,使用 OH_ResourceManager_CloseRawDir 接口释放 rawfile 目录相关资源。


OH_ResourceManager_CloseRawDir(rawDir);
复制代码


11.  根据 RawFile 实例,使用 OH_ResourceManager_GetRawFileDescriptor 接口获取 rawfile 的 RawFileDescriptor。


RawFileDescriptor descriptor;bool result = OH_ResourceManager_GetRawFileDescriptor(rawFile, descriptor);
复制代码


12.  根据 RawFileDescriptor 实例,使用 OH_ResourceManager_ReleaseRawFileDescriptor 接口关闭 rawfile 的 fd。


OH_ResourceManager_ReleaseRawFileDescriptor(descriptor);
复制代码


13.  根据 NativeResourceManager 实例,使用 OH_ResourceManager_ReleaseNativeResourceManager 接口释放 native resource manager。


OH_ResourceManager_ReleaseNativeResourceManager(nativeResourceManager);
复制代码


用户头像

每一位开发者都是华为要汇聚的星星之火 2021-10-15 加入

提供HarmonyOS关键技术解析、版本更新、开发者实践和活动资讯,欢迎各位开发者加入HarmonyOS生态,一起创造无限可能!

评论

发布
暂无评论
Native Rawfile开发指导_HarmonyOS_HarmonyOS开发者_InfoQ写作社区