OpenHarmony基線功能之文件管理
??51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)??
概述
文件管理作為操作系統(tǒng)的一個核心基本功能,為每個應(yīng)用開發(fā)者所關(guān)注,操作系統(tǒng)本身的許多功能亦基于文件,而對于應(yīng)用來說,可以說沒有文件系統(tǒng),就不能有應(yīng)用的業(yè)務(wù),可能會有很多人反駁,可以把數(shù)據(jù)保存到數(shù)據(jù)庫,但數(shù)據(jù)庫歸根結(jié)底還是文件。大家在HarmonyOS官網(wǎng)看API參考時,可以看到OpenHarmony提供了三種API:JAVA API參考、Native API參考和JS API參考。
https://developer.harmonyos.com/cn/docs/documentation/doc-references/reference-document-outline-0000001115016824。
本文將重點(diǎn)關(guān)注文件管理部分的API,試圖厘清文件管理在OpenHarmony如何從應(yīng)用到操作系統(tǒng),如何工作的。重點(diǎn)梳理三個方面:
- 文件管理都有哪些接口供應(yīng)用調(diào)用。
- 怎么調(diào)用到操作系統(tǒng)的。
- 操作系統(tǒng)怎么工作的。
希望讀者能盡可能多的參與進(jìn)來一起評論,查漏補(bǔ)缺,以便筆者逐步完善內(nèi)容,讓開源越來越好。
接口
備注:
1、限于表格限制,不會列所有,詳細(xì)可以查閱官方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也可以用標(biāo)準(zhǔn)c、c++進(jìn)行文件操作。
3、JS API @ohos.fileio提供了三種調(diào)用方式,分別是Promise、Callback和同步方式。
4、@ohos.fileio:基于手機(jī)(Phone)、平板(Tablet)、智慧屏(TV)或智能穿戴(Wearable)的模板進(jìn)行開發(fā)時使用。
5、@system.file:基于輕量級智能穿戴(Lite Wearable)的模板進(jìn)行開發(fā)時使用。
JS API文件接口的使用
接口文檔中都提供了樣例,開發(fā)者可以比較清楚地知道怎么調(diào)用API以實現(xiàn)功能。
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,在應(yīng)用代碼中調(diào)用JS API樣例。
可以看到@ohos.fileio定義在External Libraries/Gradle:ACE JS-common-3.0.0.1\common里面。
打開@ohos.fileio.d.ts可以看到所有函數(shù)的定義。
這里出現(xiàn)了一個大問號,為什么只有定義沒有實現(xiàn)呢?這里就引入下一章節(jié),是所有JS API的通用技術(shù),并非文件管理專有。因為OpenHarmony是基于Linux的,最終要調(diào)用到c實現(xiàn),對于JAVA API應(yīng)該是調(diào)用到JAVA虛擬機(jī)直接進(jìn)行文件操作,java也是c實現(xiàn)的,Native API直接調(diào)用c函數(shù)實現(xiàn),所以這里只追一下JS API是如何實現(xiàn)調(diào)用到操作系統(tǒng)api的。
NAPI
NAPI:JavaScript API框架。
介紹比較全面的,可以參見(https://harmonyos.51cto.com/posts/8390)。
模塊都有一個export()方法,將js的api映射到具體的c++函數(shù)。
實現(xiàn)
以@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、讀取參數(shù)。
2、遞歸讀取路徑readdir。
3、返回Promise或者回調(diào)。
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、讀取參數(shù)。
2、讀取路徑:readdir。
3、返回獲取到的路勁信息objDirent。
都會調(diào)到c語言標(biāo)準(zhǔn)函數(shù)。
??51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)??