OpenHarmony基线功能-本地文件管理 原创 精华

九重霄99
发布于 2022-3-8 13:37
浏览
3收藏

作者:纪春祥

概述


文件管理作为操作系统的一个核心基本功能,为每个应用开发者所关注,操作系统本身的许多功能亦基于文件,而对于应用来说,可以说没有文件系统,就不能有应用的业务,可能会有很多人反驳,可以把数据保存到数据库,但数据库归根结底还是文件。大家在HarmonyOS官网看API参考时,可以看到OpenHarmony提供了三种API:JAVA API参考、Native API参考和JS API参考。
OpenHarmony基线功能-本地文件管理-鸿蒙开发者社区
https://developer.harmonyos.com/cn/docs/documentation/doc-references/reference-document-outline-0000001115016824
本文将重点关注文件管理部分的API,试图厘清文件管理在OpenHarmony如何从应用到操作系统,如何工作的。重点梳理三个方面:

  1. 文件管理都有哪些接口供应用调用
  2. 怎么调用到操作系统的
  3. 操作系统怎么工作的
    希望读者能尽可能多的参与进来一起评论,查漏补缺,以便笔者逐步完善内容,让开源越来越好。

接口

功能 JAVA API Native API JS API JS API
- java.nio.file.Files raw_file.h、row_dir.h @ohos.fileio @system.file
查询目录 newDirectoryStream() OpenRawDir() fileio.opendir -
创建目录 createDirectory() - fileio.mkdir file.mkdir
删除目录 delete() - fileio.rmdir file.rmdir
重命名目录 move() - - -
拷贝目录 copy() - - -
读文件 readAllLines() ReadRawFile() fileio.read file.readText
写文件 write() - fileio.write file.writeText
创建文件 createFile() - fileio.openSync file.writeText
删除文件 delete() - - file.delete
重命名文件 move() - fileio.rename file.move
拷贝文件 copy() - fileio.copyFile file.copy

备注:

  1. 限于表格限制,不会列所有,详细可以查阅官方api文档:https://developer.harmonyos.com/cn/docs/documentation/doc-references/files-0000001054678506#ZH-CN_TOPIC_0000001054678506__createFile-java_nio_file_Path-java_nio_file_attribute_FileAttribute___-
  2. Native API也可以用标准c、c++进行文件操作
    OpenHarmony基线功能-本地文件管理-鸿蒙开发者社区
  3. JS API @ohos.fileio提供了三种调用方式,分别是Promise、Callback和同步方式
  4. @ohos.fileio:基于手机(Phone)、平板(Tablet)、智慧屏(TV)或智能穿戴(Wearable)的模板进行开发时使用
  5. @system.file:基于轻量级智能穿戴(Lite Wearable)的模板进行开发时使用

JS API文件接口的使用

接口文档中都提供了样例,开发者可以比较清楚地知道怎么调用API以实现功能。

import fileio from '@ohos.fileio';

let fd = fileio.openSync(path, 0o2);
let buf = new ArrayBuffer(4096);
let res = await fileio.read(fd, buf);

打开DevEco Studio 3.0.0.800,在应用代码中调用JS API样例
OpenHarmony基线功能-本地文件管理-鸿蒙开发者社区

可以看到@ohos.fileio定义在External Libraries/Gradle:ACE JS-common-3.0.0.1\common里面
OpenHarmony基线功能-本地文件管理-鸿蒙开发者社区

打开@ohos.fileio.d.ts可以看到所有函数的定义
OpenHarmony基线功能-本地文件管理-鸿蒙开发者社区

这里出现了一个大问号,为什么只有定义没有实现呢?这里就引入下一章节,是所有JS API的通用技术,并非文件管理专有。因为OpenHarmony是基于Linux的,最终要调用到c实现,对于JAVA API应该是调用到JAVA虚拟机直接进行文件操作,java也是c实现的,Native API直接调用c函数实现,所以这里只追一下JS API是如何实现调用到操作系统api的。

NAPI

NAPI:JavaScript API框架
介绍比较全面的,可以参见(https://harmonyos.51cto.com/posts/8390)
OpenHarmony基线功能-本地文件管理-鸿蒙开发者社区

模块都有一个export()方法,将js的api映射到具体的c++函数,
OpenHarmony基线功能-本地文件管理-鸿蒙开发者社区

实现

以@fileio.read和@fileio.readSync为例:

${KaihongOS}\foundation\distributeddatamgr\distributedfile\interfaces\kits\js\src\mod_fileio\class_dir\dir_n_exporter.cpp

napi_value DirNExporter::Read(napi_env env, napi_callback_info info)
{
    NFuncArg funcArg(env, info);
    if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ONE)) {
        UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
        return nullptr;
    }

    auto dirEntity = NClass::GetEntityOf<DirEntity>(env, funcArg.GetThisVar());
    if (!dirEntity) {
        UniError(EIO).ThrowErr(env, "Cannot get entity of Dir");
        return nullptr;
    }

    if (!dirEntity || !dirEntity->dir_) {
        UniError(EBADF).ThrowErr(env, "Dir has been closed yet");
        return nullptr;
    }

    DIR *dir = dirEntity->dir_.get();
    auto arg = make_shared<DirReadArgs>(NVal(env, funcArg.GetThisVar()));
    auto cbExec = [arg, dir, dirEntity](napi_env env) -> UniError {
        struct dirent tmpDirent;
        lock_guard(dirEntity->lock_);
        errno = 0;
        dirent *res = nullptr;
        do {
            res = readdir(dir);
            if (res == nullptr && errno) {
                return UniError(errno);
            } else if (res == nullptr) {
                return UniError(ERRNO_NOERR);
            } else if (string(res->d_name) == "." || string(res->d_name) == "..") {
                continue;
            } else {
                tmpDirent = *res;
                break;
            }
        } while (true);

        arg->dirRes = tmpDirent;
        return UniError(ERRNO_NOERR);
    };
    auto cbCompl = [arg](napi_env env, UniError err) -> NVal {
        return DoReadCompile(env, err, arg);
    };
    NVal thisVar(env, funcArg.GetThisVar());

    if (funcArg.GetArgc() == NARG_CNT::ZERO) {
        return NAsyncWorkPromise(env, thisVar).Schedule("fileioDirRead", cbExec, cbCompl).val_;
    } else {
        NVal cb(env, funcArg[NARG_POS::FIRST]);
        return NAsyncWorkCallback(env, thisVar, cb).Schedule("fileioDirRead", cbExec, cbCompl).val_;
    }
}

1、读取参数
2、递归读取路径readdir
3、返回Promise或者回调

napi_value DirNExporter::ReadSync(napi_env env, napi_callback_info info)
{
    NFuncArg funcArg(env, info);
    if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
        UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
        return nullptr;
    }
    
    DirEntity *dirEntity = GetDirEntity(env, info);
    if (!dirEntity || !dirEntity->dir_) {
        UniError(EBADF).ThrowErr(env, "Dir has been closed yet");
        return nullptr;
    }

    struct dirent tmpDirent;
    {
        lock_guard(dirEntity->lock_);
        errno = 0;
        dirent *res = nullptr;
        do {
            res = readdir(dirEntity->dir_.get());
            if (res == nullptr && errno) {
                UniError(errno).ThrowErr(env);
                return nullptr;
            } else if (res == nullptr) {
                return NVal::CreateUndefined(env).val_;
            } else if (string(res->d_name) == "." || string(res->d_name) == "..") {
                continue;
            } else {
                tmpDirent = *res;
                break;
            }
        } while (true);
    }

    napi_value objDirent = NClass::InstantiateClass(env, DirentNExporter::className_, {});
    if (!objDirent) {
        return nullptr;
    }

    auto direntEntity = NClass::GetEntityOf<DirentEntity>(env, objDirent);
    if (!direntEntity) {
        return nullptr;
    }
    direntEntity->dirent_ = tmpDirent;

    return objDirent;
}

1、读取参数
2、读取路径:readdir
3、返回获取到的路劲信息objDirent
都会调到c语言标准函数

代码结构

路径 功能 状态
OpenHarmony基线功能-本地文件管理-鸿蒙开发者社区${foundation}\distributeddatamgr\distributedfile\interfaces\kits\js\src js本地文件管理 已经实现,但不是分布式文件,而是本地文件管理接口
OpenHarmony基线功能-本地文件管理-鸿蒙开发者社区${foundation}\distributeddatamgr\distributedfile\interfaces\kits\napi - 没有参与编译
OpenHarmony基线功能-本地文件管理-鸿蒙开发者社区${foundation}\distributeddatamgr\distributedfile\interfaces\kits\native - 没有参与编译
OpenHarmony基线功能-本地文件管理-鸿蒙开发者社区${foundation}\distributeddatamgr\distributedfile\utils\filemgmt_libhilog - 没有参与编译
OpenHarmony基线功能-本地文件管理-鸿蒙开发者社区${foundation}\distributeddatamgr\distributedfile\utils\filemgmt_libn 异步调用机制:NAsyncWorkPromise和NAsyncWorkCallback 已经实现

更多原创内容请关注:深开鸿技术团队

入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2022-4-6 10:12:27修改
5
收藏 3
回复
举报
1条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

学习Linux时就有一切皆文件的说法,文件管理无论在哪里都很重要

回复
2022-3-8 14:13:40
回复
    相关推荐