采得百花成蜜后,为谁辛苦为谁甜。这篇文章主要讲述OpenHarmony基线功能之文件管理相关的知识,希望能为你提供帮助。
作者:纪春祥
概述文件管理作为操作系统的一个核心基本功能,为每个应用开发者所关注,操作系统本身的许多功能亦基于文件,而对于应用来说,可以说没有文件系统,就不能有应用的业务,可能会有很多人反驳,可以把数据保存到数据库,但数据库归根结底还是文件。大家在HarmonyOS官网看API参考时,可以看到OpenHarmony提供了三种API:java API参考、Native API参考和JS API参考。
文章图片
https://developer.harmonyos.com/cn/docs/documentation/doc-references/reference-document-outline-0000001115016824
本文将重点关注文件管理部分的API,试图厘清文件管理在OpenHarmony如何从应用到操作系统,如何工作的。重点梳理三个方面:
- 文件管理都有哪些接口供应用调用
- 怎么调用到操作系统的
- 操作系统怎么工作的
希望读者能尽可能多的参与进来一起评论,查漏补缺,以便笔者逐步完善内容,让开源越来越好。
功能 | 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 |
- 限于表格限制,不会列所有,详细可以查阅官方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___-
- Native API也可以用标准c、c++进行文件操作
文章图片
- JS API @ohos.fileio提供了三种调用方式,分别是Promise、Callback和同步方式
- @ohos.fileio:基于手机(Phone)、平板(Tablet)、智慧屏(TV)或智能穿戴(Wearable)的模板进行开发时使用
- @system.file:基于轻量级智能穿戴(Lite Wearable)的模板进行开发时使用
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样例
文章图片
可以看到@ohos.fileio定义在External Libraries/Gradle:ACE JS-common-3.0.0.1\\common里面
文章图片
打开@ohos.fileio.d.ts可以看到所有函数的定义
文章图片
这里出现了一个大问号,为什么只有定义没有实现呢?这里就引入下一章节,是所有JS API的通用技术,并非文件管理专有。因为OpenHarmony是基于Linux的,最终要调用到c实现,对于JAVA API应该是调用到JAVA虚拟机直接进行文件操作,java也是c实现的,Native API直接调用c函数实现,所以这里只追一下JS API是如何实现调用到操作系统api的。
NAPINAPI:javascript API框架
介绍比较全面的,可以参见(https://harmonyos.51cto.com/posts/8390)
文章图片
模块都有一个export()方法,将js的api映射到具体的c++函数,
文章图片
实现以@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语言标准函数
更多原创内容请关注:深开鸿技术团队入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。
想了解更多关于鸿蒙的内容,请访问:
51CTO和华为官方合作共建的鸿蒙技术社区
https://ost.51cto.com/#bkwz
::: hljs-center
文章图片
【OpenHarmony基线功能之文件管理】:::
推荐阅读
- docker-compose概述与编排部署
- RocketMQ高可用设计之消息重试机制
- 14 款命令行常用工具的替代品!
- Hello Blazor(启用深色模式 #yyds干货盘点#)
- PMP相关的十八种图总结及图例
- GDP Streaming RPC 设计
- Spring源码解析之八finishBeanFactoryInitialization方法即初始化单例bean
- redis存储token
- Linux i2c子系统驱动probe