diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index 36e610de8d6b3457a20683d60ed8f5d6ebefdf93..3702555082812b786f5ee21f0e08af931925c25a 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -99,6 +99,30 @@ ohos_shared_library("fileio") { external_deps = [ "hiviewdfx_hilog_native:libhilog" ] } +ohos_shared_library("fs") { + subsystem_name = "filemanagement" + part_name = "file_api" + + relative_install_dir = "module/file" + + include_dirs = [ + "//foundation/filemanagement/file_api/interfaces/kits/js/src/common/file_helper", + "//foundation/filemanagement/file_api/interfaces/kits/js/src/common/napi", + "//foundation/filemanagement/file_api/interfaces/kits/js/src/common/napi/n_async", + ] + + sources = file_common_src + sources += [ + "src/mod_fileio/common_func.cpp", + "src/mod_fileio/module_v9.cpp", + "src/mod_fileio/properties/prop_n_exporter_v9.cpp", + ] + + deps = [ "//foundation/arkui/napi:ace_napi" ] + + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] +} + ohos_shared_library("file") { subsystem_name = "filemanagement" part_name = "file_api" @@ -241,6 +265,7 @@ group("build_kits_js") { ":environment", ":file", ":fileio", + ":fs", ":securitylabel", ":statfs", ] diff --git a/interfaces/kits/js/src/mod_fileio/common_func.cpp b/interfaces/kits/js/src/mod_fileio/common_func.cpp index b54748f122373b989e8e90fb46978572aa275f6e..1d098f6f1e08ead9856dc4edd0eb5a71aeece622 100644 --- a/interfaces/kits/js/src/mod_fileio/common_func.cpp +++ b/interfaces/kits/js/src/mod_fileio/common_func.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -40,10 +40,12 @@ static tuple GetActualBuf(napi_env env, void *rawBuf, int64_t if (op.HasProp("offset")) { tie(succ, opOffset) = op.GetProp("offset").ToInt64(); if (!succ || opOffset < 0) { - UniError(EINVAL).ThrowErr(env, "Invalid option.offset, positive integer is desired"); + HILOGE("Invalid option.offset, positive integer is desired"); + UniError(EINVAL).ThrowErr(env); return { false, nullptr, opOffset }; } else if (opOffset > bufLen) { - UniError(EINVAL).ThrowErr(env, "Invalid option.offset, buffer limit exceeded"); + HILOGE("Invalid option.offset, buffer limit exceeded"); + UniError(EINVAL).ThrowErr(env); return { false, nullptr, opOffset }; } else { realBuf = static_cast(rawBuf) + opOffset; @@ -64,13 +66,15 @@ static tuple GetActualLen(napi_env env, int64_t bufLen, int64_t bu int64_t opLength; tie(succ, opLength) = op.GetProp("length").ToInt64(); if (!succ) { - UniError(EINVAL).ThrowErr(env, "Invalid option.length, expect integer"); + HILOGE("Invalid option.length, expect integer"); + UniError(EINVAL).ThrowErr(env); return { false, 0 }; } if (opLength < 0) { retLen = bufLen - bufOff; } else if (opLength + bufOff > bufLen) { - UniError(EINVAL).ThrowErr(env, "Invalid option.length, buffer limit exceeded"); + HILOGE("Invalid option.length, buffer limit exceeded"); + UniError(EINVAL).ThrowErr(env); return { false, 0 }; } else { retLen = opLength; @@ -128,7 +132,6 @@ tuple, unique_ptr> CommonFunc::GetCopyPathArg(n if (!succ) { return { false, nullptr, nullptr }; } - return make_tuple(true, move(src), move(dest)); } @@ -148,7 +151,8 @@ tuple CommonFunc::GetReadArg(napi_env int offset = 0; tie(succ, buf, bufLen) = txt.ToArraybuffer(); if (!succ) { - UniError(EINVAL).ThrowErr(env, "Invalid read buffer, expect arraybuffer"); + HILOGE("Invalid read buffer, expect arraybuffer"); + UniError(EINVAL).ThrowErr(env); return { false, nullptr, 0, posAssigned, position, offset }; } @@ -169,7 +173,8 @@ tuple CommonFunc::GetReadArg(napi_env if (succ && position >= 0) { posAssigned = true; } else { - UniError(EINVAL).ThrowErr(env, "option.position shall be positive number"); + HILOGE("option.position shall be positive number"); + UniError(EINVAL).ThrowErr(env); return { false, nullptr, 0, posAssigned, position, offset }; } } @@ -223,7 +228,8 @@ tuple, void *, int64_t, bool, int64_t> CommonFunc::GetW if (!succ) { tie(succ, buf, bufLen) = NVal(env, argWBuf).ToArraybuffer(); if (!succ) { - UniError(EINVAL).ThrowErr(env, "Illegal write buffer or encoding"); + HILOGE("Illegal write buffer or encoding"); + UniError(EINVAL).ThrowErr(env); return { false, nullptr, nullptr, 0, hasPos, retPos }; } } else { @@ -241,12 +247,12 @@ tuple, void *, int64_t, bool, int64_t> CommonFunc::GetW return { false, nullptr, nullptr, 0, hasPos, retPos }; } - /* To parse options - Where to begin writing */ if (op.HasProp("position")) { int32_t position = 0; tie(succ, position) = op.GetProp("position").ToInt32(); if (!succ || position < 0) { - UniError(EINVAL).ThrowErr(env, "option.position shall be positive number"); + HILOGE("option.position shall be positive number"); + UniError(EINVAL).ThrowErr(env); return { false, nullptr, nullptr, 0, hasPos, retPos }; } hasPos = true; @@ -254,9 +260,91 @@ tuple, void *, int64_t, bool, int64_t> CommonFunc::GetW } else { retPos = INVALID_POSITION; } - return { true, move(bufferGuard), retBuf, retLen, hasPos, retPos }; } + +tuple CommonFunc::GetReadArgV9(napi_env env, + napi_value readBuf, napi_value option) +{ + bool succ = false; + int64_t retLen; + bool posAssigned = false; + int64_t position; + + NVal txt(env, readBuf); + void *buf = nullptr; + int64_t bufLen; + tie(succ, buf, bufLen) = txt.ToArraybuffer(); + if (!succ) { + HILOGE("Invalid read buffer, expect arraybuffer"); + UniError(EINVAL).ThrowErr(env); + return { false, nullptr, 0, posAssigned, position }; + } + NVal op = NVal(env, option); + tie(succ, retLen) = GetActualLen(env, bufLen, 0, op); + if (!succ) { + return { false, nullptr, 0, posAssigned, position }; + } + + if (op.HasProp("offset")) { + tie(succ, position) = op.GetProp("offset").ToInt64(); + if (succ && position >= 0) { + posAssigned = true; + } else { + HILOGE("option.offset shall be positive number"); + UniError(EINVAL).ThrowErr(env); + return { false, nullptr, 0, posAssigned, position }; + } + } + + return { true, buf, retLen, posAssigned, position }; +} + +tuple, void *, int64_t, bool, int64_t> CommonFunc::GetWriteArgV9(napi_env env, + napi_value argWBuf, napi_value argOption) +{ + int64_t retLen; + bool hasPos = false; + int64_t retPos; + + bool succ = false; + void *buf = nullptr; + int64_t bufLen; + NVal op(env, argOption); + NVal jsBuffer(env, argWBuf); + unique_ptr bufferGuard; + tie(succ, bufferGuard, bufLen) = DecodeString(env, jsBuffer, op.GetProp("encoding")); + if (!succ) { + tie(succ, buf, bufLen) = NVal(env, argWBuf).ToArraybuffer(); + if (!succ) { + HILOGE("Illegal write buffer or encoding"); + UniError(EINVAL).ThrowErr(env); + return { false, nullptr, nullptr, 0, hasPos, retPos }; + } + } else { + buf = bufferGuard.get(); + } + tie(succ, retLen) = GetActualLen(env, bufLen, 0, op); + if (!succ) { + return { false, nullptr, nullptr, 0, hasPos, retPos }; + } + + if (op.HasProp("offset")) { + int32_t position = 0; + tie(succ, position) = op.GetProp("offset").ToInt32(); + if (!succ || position < 0) { + HILOGE("option.offset shall be positive number"); + UniError(EINVAL).ThrowErr(env); + return { false, nullptr, nullptr, 0, hasPos, retPos }; + } + hasPos = true; + retPos = position; + } else { + retPos = INVALID_POSITION; + } + return { true, move(bufferGuard), buf, retLen, hasPos, retPos }; +} + } // namespace ModuleFileIO } // namespace DistributedFS } // namespace OHOS diff --git a/interfaces/kits/js/src/mod_fileio/common_func.h b/interfaces/kits/js/src/mod_fileio/common_func.h index 337826536d5244b74bb98cd90915b019d52bae0e..5c0adb2e152434e9ae4ea3b1a673ecca09c9a33d 100644 --- a/interfaces/kits/js/src/mod_fileio/common_func.h +++ b/interfaces/kits/js/src/mod_fileio/common_func.h @@ -28,12 +28,16 @@ struct CommonFunc { static std::tuple GetReadArg(napi_env env, napi_value readBuf, napi_value option); + static std::tuple GetReadArgV9(napi_env env, + napi_value readBuf, + napi_value option); static std::tuple, void *, int64_t, bool, int64_t> GetWriteArg(napi_env env, napi_value argWBuf, napi_value argOption); + static std::tuple, void *, int64_t, bool, int64_t> GetWriteArgV9(napi_env env, + napi_value argWBuf, napi_value argOption); static std::tuple, std::unique_ptr> GetCopyPathArg(napi_env env, - napi_value srcPath, - napi_value dstPath); + napi_value srcPath, napi_value dstPath); }; } // namespace ModuleFileIO } // namespace DistributedFS diff --git a/interfaces/kits/js/src/mod_fileio/module_v9.cpp b/interfaces/kits/js/src/mod_fileio/module_v9.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fe757490e42f3fdeda10b2745a409dcd35bdc31a --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/module_v9.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "../common/log.h" +#include "properties/prop_n_exporter_v9.h" + +using namespace std; + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +static napi_value Export(napi_env env, napi_value exports) +{ + std::vector> products; + products.emplace_back(make_unique(env, exports)); + + for (auto &&product : products) { + if (!product->Export()) { + HILOGE("INNER BUG. Failed to export class %{public}s for module fileio", product->GetClassName().c_str()); + return nullptr; + } else { + HILOGE("Class %{public}s for module fileio has been exported", product->GetClassName().c_str()); + } + } + return exports; +} + +NAPI_MODULE(fs, Export) +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter_v9.cpp b/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter_v9.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6efa9e8dfb487abbe1554f5fb0172dc6f4a14941 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter_v9.cpp @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "prop_n_exporter_v9.h" + +#include +#include +#include +#include +#include +#include + +#include "../common_func.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +using namespace std; + +napi_value PropNExporterV9::ReadSync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + + if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::THREE)) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + + bool succ = false; + int fd = 0; + tie(succ, fd) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!succ) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + + void *buf = nullptr; + int64_t len = 0; + bool hasPos = false; + int64_t pos = 0; + tie(succ, buf, len, hasPos, pos) = + CommonFunc::GetReadArgV9(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); + if (!succ) { + return nullptr; + } + + ssize_t actLen; + if (hasPos) { + actLen = pread(fd, buf, len, pos); + } else { + actLen = read(fd, buf, len); + } + if (actLen == -1) { + UniError(errno).ThrowErr(env); + return nullptr; + } + + return NVal::CreateInt64(env, actLen).val_; +} + +struct AsyncIOReadArg { + ssize_t lenRead { 0 }; +}; + +static UniError ReadExec(shared_ptr arg, void *buf, size_t len, int fd, size_t position) +{ + if (position == (size_t)INVALID_POSITION) { + arg->lenRead = write(fd, buf, len); + } else { + arg->lenRead = pwrite(fd, buf, len, position); + } + + if (arg->lenRead == -1) { + return UniError(errno); + } else { + return UniError(ERRNO_NOERR); + } +} + +napi_value PropNExporterV9::Read(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::FOUR)) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + + bool succ = false; + void *buf = nullptr; + int64_t len = 0; + int fd = 0; + bool hasPos = false; + int64_t pos = 0; + tie(succ, fd) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!succ) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + + tie(succ, buf, len, hasPos, pos) = + CommonFunc::GetReadArgV9(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); + if (!succ) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + + auto arg = make_shared(); + auto cbExec = [arg, buf, len, fd, pos](napi_env env) -> UniError { + return ReadExec(arg, buf, len, fd, pos); + }; + + auto cbCompl = [arg](napi_env env, UniError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } + return { NVal::CreateInt64(env, arg->lenRead) }; + }; + + NVal thisVar(env, funcArg.GetThisVar()); + bool hasOp = false; + if (funcArg.GetArgc() == NARG_CNT::THREE) { + NVal op = NVal(env, funcArg[NARG_POS::THIRD]); + if (op.HasProp("offset") || op.HasProp("length")) { + hasOp = true; + } + } + if (funcArg.GetArgc() == NARG_CNT::TWO || (funcArg.GetArgc() == NARG_CNT::THREE && hasOp)) { + return NAsyncWorkPromise(env, thisVar).Schedule("FileIORead", cbExec, cbCompl).val_; + } else { + int cbIdx = ((funcArg.GetArgc() == NARG_CNT::THREE) ? NARG_POS::THIRD : NARG_POS::FOURTH); + NVal cb(env, funcArg[cbIdx]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule("FileIORead", cbExec, cbCompl).val_; + } + + return NVal::CreateUndefined(env).val_; +} + +UniError PropNExporterV9::WriteExec(shared_ptr arg, void *buf, size_t len, int fd, size_t position) +{ + if (position == (size_t)INVALID_POSITION) { + arg->actLen = write(fd, buf, len); + } else { + arg->actLen = pwrite(fd, buf, len, position); + } + + if (arg->actLen == -1) { + return UniError(errno); + } else { + return UniError(ERRNO_NOERR); + } +} + +napi_value PropNExporterV9::Write(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::FOUR)) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + + bool succ = false; + int fd; + tie(succ, fd) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!succ) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + + unique_ptr bufGuard; + void *buf = nullptr; + size_t len = 0; + size_t position = 0; + bool hasPos = false; + tie(succ, bufGuard, buf, len, hasPos, position) = + CommonFunc::GetWriteArgV9(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); + if (!succ) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + + shared_ptr arg; + if (bufGuard) { + arg = make_shared(move(bufGuard)); + } else { + arg = make_shared(NVal(env, funcArg[NARG_POS::SECOND])); + } + auto cbExec = [arg, buf, len, fd, position](napi_env env) -> UniError { + return WriteExec(arg, buf, len, fd, position); + }; + + auto cbCompl = [arg](napi_env env, UniError err) -> NVal { + if (err) { + return { env, err.GetNapiErr(env) }; + } else { + return { NVal::CreateInt64(env, arg->actLen) }; + } + }; + + NVal thisVar(env, funcArg.GetThisVar()); + bool hasOp = false; + if (funcArg.GetArgc() == NARG_CNT::THREE) { + NVal op = NVal(env, funcArg[NARG_POS::THIRD]); + if (op.HasProp("offset") || op.HasProp("position") || op.HasProp("length") || op.HasProp("encoding")) { + hasOp = true; + } + } + + if (funcArg.GetArgc() == NARG_CNT::TWO || (funcArg.GetArgc() == NARG_CNT::THREE && hasOp)) { + return NAsyncWorkPromise(env, thisVar).Schedule("FileIOWrite", cbExec, cbCompl).val_; + } else { + int cbIdx = ((funcArg.GetArgc() == NARG_CNT::THREE) ? NARG_POS::THIRD : NARG_POS::FOURTH); + NVal cb(env, funcArg[cbIdx]); + return NAsyncWorkCallback(env, thisVar, cb).Schedule("FileIOWrite", cbExec, cbCompl).val_; + } + + return NVal::CreateUndefined(env).val_; +} + +napi_value PropNExporterV9::WriteSync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::THREE)) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + + bool succ = false; + int fd; + tie(succ, fd) = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!succ) { + UniError(EINVAL).ThrowErr(env); + return nullptr; + } + + void *buf = nullptr; + size_t len = 0; + size_t position = 0; + unique_ptr bufGuard; + bool hasPos = false; + tie(succ, bufGuard, buf, len, hasPos, position) = + CommonFunc::GetWriteArgV9(env, funcArg[NARG_POS::SECOND], funcArg[NARG_POS::THIRD]); + if (!succ) { + return nullptr; + } + + ssize_t writeLen; + if (position == (size_t)INVALID_POSITION) { + writeLen = write(fd, buf, len); + } else { + writeLen = pwrite(fd, buf, len, position); + } + + if (writeLen == -1) { + UniError(errno).ThrowErr(env); + return nullptr; + } + + return NVal::CreateInt64(env, writeLen).val_; +} + +bool PropNExporterV9::Export() +{ + return exports_.AddProp({ + NVal::DeclareNapiFunction("read", Read), + NVal::DeclareNapiFunction("readSync", ReadSync), + NVal::DeclareNapiFunction("write", Write), + NVal::DeclareNapiFunction("writeSync", WriteSync), + }); +} + +string PropNExporterV9::GetClassName() +{ + return PropNExporterV9::className_; +} + +PropNExporterV9::PropNExporterV9(napi_env env, napi_value exports) : NExporter(env, exports) {} + +PropNExporterV9::~PropNExporterV9() {} +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS diff --git a/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter_v9.h b/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter_v9.h new file mode 100644 index 0000000000000000000000000000000000000000..c7d0d96193d493260a7dd106f18f503c564526c9 --- /dev/null +++ b/interfaces/kits/js/src/mod_fileio/properties/prop_n_exporter_v9.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_SRC_MOD_FILEIO_PROPERTIES_PROP_N_EXPORTER_V9_H +#define INTERFACES_KITS_JS_SRC_MOD_FILEIO_PROPERTIES_PROP_N_EXPORTER_V9_H + +#include "../../common/log.h" +#include "../../common/napi/n_async/n_async_work_callback.h" +#include "../../common/napi/n_async/n_async_work_promise.h" +#include "../../common/napi/n_async/n_ref.h" +#include "../../common/napi/n_exporter.h" +#include "../../common/napi/n_func_arg.h" +#include "../../common/napi/n_val.h" +#include "../../common/uni_error.h" + +namespace OHOS { +namespace DistributedFS { +namespace ModuleFileIO { +struct AsyncIOWrtieArg { + NRef refWriteArrayBuf_; + std::unique_ptr guardWriteStr_; + ssize_t actLen = 0; + + explicit AsyncIOWrtieArg(NVal refWriteArrayBuf) : refWriteArrayBuf_(refWriteArrayBuf) {} + explicit AsyncIOWrtieArg(std::unique_ptr &&guardWriteStr) : guardWriteStr_(move(guardWriteStr)) {} + ~AsyncIOWrtieArg() = default; +}; + +class PropNExporterV9 final : public NExporter { +public: + inline static const std::string className_ = "__properitiesV9__"; + + static napi_value ReadSync(napi_env env, napi_callback_info info); + static napi_value WriteSync(napi_env env, napi_callback_info info); + static napi_value Read(napi_env env, napi_callback_info info); + static napi_value Write(napi_env env, napi_callback_info info); + static UniError WriteExec(std::shared_ptr arg, void *buf, size_t len, int fd, size_t position); + bool Export() override; + std::string GetClassName() override; + + PropNExporterV9(napi_env env, napi_value exports); + ~PropNExporterV9() override; +}; +} // namespace ModuleFileIO +} // namespace DistributedFS +} // namespace OHOS +#endif \ No newline at end of file