diff --git a/entry/oh_modules/libfile_access.so/Index.d.ts b/entry/oh_modules/libfile_access.so/Index.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..22ba0cbeb9cac5eed2622fa52f3f18fb2b845775 --- /dev/null +++ b/entry/oh_modules/libfile_access.so/Index.d.ts @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024 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. + */ +/** + * 最佳实践:Native侧实现文件访问开发实践 + */ +import { resourceManager } from '@kit.LocalizationKit'; +// [Start box_path] +export const transferSandboxPath: (path: string, contents: string) => void; +// [End box_path] +// [Start splice1] +export const splicePath: (contents: string) => void; +// [End splice1] +// [Start tran_source_mg] +export const transferResourceMgr: (resMgr: resourceManager.ResourceManager, path: string) => string; +// [End tran_source_mg] +// [Start write_file_pick] +export const writeFileUsingPickerFd: (fd: number, contents: string) => string; +// [End write_file_pick] +// [Start read_fire_fd] +export const readFileUsingPickerFd: (fd: number) => string; +// [End read_fire_fd] \ No newline at end of file diff --git a/entry/src/main/cpp/FileAccessMethods.cpp b/entry/src/main/cpp/FileAccessMethods.cpp index 8b8589f5123178c026a72cf0981cfd707d46c30c..4c588e88fd64d4d0a26a8f574e96e24e3b4255d0 100644 --- a/entry/src/main/cpp/FileAccessMethods.cpp +++ b/entry/src/main/cpp/FileAccessMethods.cpp @@ -12,7 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +/** + * 最佳实践:Native侧实现文件访问开发实践 + */ #include "napi/native_api.h" #include "hilog/log.h" #include @@ -23,7 +25,7 @@ const int DOMAIN = 0xFF00; const char *TAG = "[FileAccessMethods]"; - +// [Start napi_value] static napi_value TransferSandboxPath(napi_env env, napi_callback_info info) { size_t argc = 2; napi_value argv[2] = {nullptr}; @@ -31,68 +33,96 @@ static napi_value TransferSandboxPath(napi_env env, napi_callback_info info) { size_t pathSize, contentsSize; char pathBuf[256], contentsBuf[256]; + // [Start get_path] napi_get_value_string_utf8(env, argv[0], pathBuf, sizeof(pathBuf), &pathSize); napi_get_value_string_utf8(env, argv[1], contentsBuf, sizeof(contentsBuf), &contentsSize); - + // [End get_path] snprintf(pathBuf, sizeof(pathBuf), "%s/TransferSandboxPath.txt", pathBuf); + // [Start fp] FILE *fp; fp = fopen(pathBuf, "w"); + // [End fp] if (fp == nullptr) { OH_LOG_Print(LOG_APP, LOG_ERROR, DOMAIN, TAG, "Open file error!"); return nullptr; } OH_LOG_Print(LOG_APP, LOG_INFO, DOMAIN, TAG, "Open file successfully!"); + // [Start contentsBuf] fprintf(fp, "%s", contentsBuf); + // [End contentsBuf] fclose(fp); return nullptr; } - +// [End napi_value] +// [Start splice_path] static napi_value SplicePath(napi_env env, napi_callback_info info) { size_t argc = 1; napi_value argv[1] = {nullptr}; napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); - + //Splice the sandbox path according to the actual file location. size_t contentsSize; + // [Start path_buf] char pathBuf[256] = "/data/storage/el2/base/haps/entry/files/SplicePath.txt"; + // [End path_buf] + //Convert the contents of the text to be written into C-side variables through the Node-API interface. char contentsBuf[256]; + // [Start value_utf8] + // [Start value_string] napi_get_value_string_utf8(env, argv[0], contentsBuf, sizeof(contentsBuf), &contentsSize); - + // [End value_string] + // [End value_utf8] + // [Start fp1] + //Open the file through the specified path. FILE *fp; fp = fopen(pathBuf, "w"); + // [End fp1] if (fp == nullptr) { OH_LOG_Print(LOG_APP, LOG_ERROR, DOMAIN, TAG, "Open file error!"); return nullptr; } OH_LOG_Print(LOG_APP, LOG_INFO, DOMAIN, TAG, "Open file successfully!"); + // [Start fp_buf] + //Write a file using the file operation function of the C standard library. fprintf(fp, "%s", contentsBuf); + // [End fp_buf] fclose(fp); return nullptr; } - +// [End splice_path] +// [Start source_mg] static napi_value TransferResourceMgr(napi_env env, napi_callback_info info) { size_t argc = 2; napi_value argv[2] = {nullptr}; napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); - + // [Start native_manage] + //Convert the incoming resource manager object into a Native object. NativeResourceManager *mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[0]); + // [End native_manage] size_t fileNameSize; char fileNameBuf[256]; + //Convert the passed-in file name into a C-side variable through the Node-API interface. napi_get_value_string_utf8(env, argv[1], fileNameBuf, sizeof(fileNameBuf), &fileNameSize); + // [Start open_raw_file] + //Open a file through a resource object RawFile *rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, fileNameBuf); + // [End open_raw_file] if (rawFile != nullptr) { OH_LOG_Print(LOG_APP, LOG_INFO, DOMAIN, TAG, "OH_ResourceManager_OpenRawFile success."); } - + // [Start long_len] + //Read the file content through the resource object long len = OH_ResourceManager_GetRawFileSize(rawFile); std::unique_ptr data = std::make_unique(len); OH_ResourceManager_ReadRawFile(rawFile, data.get(), len); + // [End long_len] OH_ResourceManager_CloseRawFile(rawFile); OH_ResourceManager_ReleaseNativeResourceManager(mNativeResMgr); napi_value contents; napi_create_string_utf8(env, data.get(), len, &contents); return contents; } - +// [End source_mg] +// [Start write_pick] static napi_value WriteFileUsingPickerFd(napi_env env, napi_callback_info info) { size_t argc = 2; napi_value argv[2] = {nullptr}; @@ -101,12 +131,19 @@ static napi_value WriteFileUsingPickerFd(napi_env env, napi_callback_info info) unsigned int fd = -1; size_t contentsSize; char contentsBuf[256]; + // [Start uint_get] + //Convert the incoming file descriptor and the contents to be written into the file into C-side variables. napi_get_value_uint32(env, argv[0], &fd); napi_get_value_string_utf8(env, argv[1], contentsBuf, sizeof(contentsBuf), &contentsSize); - + // [End uint_get] ftruncate(fd, 0); + // [Start size_buf] + //Write a file using the file operation function of the C standard library. size_t buffSize = write(fd, contentsBuf, contentsSize); + // [End size_buf] + // [Start std_res] std::string res; + //According to the return value of the write function, judge whether the operation returns the result successfully. napi_value contents; if (buffSize == -1) { res = "Write File Failed!"; @@ -117,18 +154,27 @@ static napi_value WriteFileUsingPickerFd(napi_env env, napi_callback_info info) } napi_create_string_utf8(env, res.c_str(), sizeof(res), &contents); return contents; + // [End std_res] } - +// [End write_pick] + // [Start read_file_pick] static napi_value ReadFileUsingPickerFd(napi_env env, napi_callback_info info) { size_t argc = 1; napi_value argv[1] = {nullptr}; napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); unsigned int fd = -1; + // [Start uint32_env] + //Convert the incoming file descriptor into a C-side variable. napi_get_value_uint32(env, argv[0], &fd); - + // [End uint32_env] + // [Start buff_char] + //Use the file operation function of the C standard library to read the file. char buff[1000]; size_t buffSize = read(fd, buff, sizeof(buff)); + // [End buff_char] + // [Start content_value] + //Judge whether the reading is successful or not and return the file content. napi_value contents; if (buffSize == -1) { OH_LOG_Print(LOG_APP, LOG_ERROR, DOMAIN, TAG, "Read File Failed!!!"); @@ -137,7 +183,9 @@ static napi_value ReadFileUsingPickerFd(napi_env env, napi_callback_info info) { napi_create_string_utf8(env, buff, buffSize, &contents); } return contents; + // [End content_value] } + // [End read_file_pick] EXTERN_C_START static napi_value Init(napi_env env, napi_value exports) { diff --git a/entry/src/main/cpp/types/libfile_access/Index.d.ts b/entry/src/main/cpp/types/libfile_access/Index.d.ts index 42824fc97eb065864c0d2012440830aa5050405b..22ba0cbeb9cac5eed2622fa52f3f18fb2b845775 100644 --- a/entry/src/main/cpp/types/libfile_access/Index.d.ts +++ b/entry/src/main/cpp/types/libfile_access/Index.d.ts @@ -12,15 +12,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +/** + * 最佳实践:Native侧实现文件访问开发实践 + */ import { resourceManager } from '@kit.LocalizationKit'; - +// [Start box_path] export const transferSandboxPath: (path: string, contents: string) => void; - +// [End box_path] +// [Start splice1] export const splicePath: (contents: string) => void; - +// [End splice1] +// [Start tran_source_mg] export const transferResourceMgr: (resMgr: resourceManager.ResourceManager, path: string) => string; - +// [End tran_source_mg] +// [Start write_file_pick] export const writeFileUsingPickerFd: (fd: number, contents: string) => string; - -export const readFileUsingPickerFd: (fd: number) => string; \ No newline at end of file +// [End write_file_pick] +// [Start read_fire_fd] +export const readFileUsingPickerFd: (fd: number) => string; +// [End read_fire_fd] \ No newline at end of file diff --git a/entry/src/main/ets/common/utils/FileOperate.ets b/entry/src/main/ets/common/utils/FileOperate.ets index e14ac9a5d14b18143f3d43ad1b97c8271c52057a..efe76c5f0c60ee017624df0b52170bf9a2f88a7f 100644 --- a/entry/src/main/ets/common/utils/FileOperate.ets +++ b/entry/src/main/ets/common/utils/FileOperate.ets @@ -12,13 +12,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +/** + * 最佳实践:Native侧实现文件访问开发实践 + */ import { common } from '@kit.AbilityKit'; import { BusinessError } from '@kit.BasicServicesKit'; import { fileIo as fs, fileUri, picker } from '@kit.CoreFileKit'; import Logger from '../utils/Logger'; +// [Start file_access1] import FileAccess from 'libfile_access.so'; - +// [End file_access1] function CreateFileByPicker(context: common.Context, fileName: string) { let documentSaveOptions = new picker.DocumentSaveOptions(); documentSaveOptions.newFileNames = [fileName]; @@ -29,20 +32,23 @@ function CreateFileByPicker(context: common.Context, fileName: string) { Logger.error('DocumentViewPicker.save failed with err: ' + JSON.stringify(error)); }); } - +// [Start by_pick] async function WriteFileByPicker(contents: string): Promise { + //Configure picker Selection Information const documentSelectOptions = new picker.DocumentSelectOptions(); documentSelectOptions.maxSelectNumber = 1; documentSelectOptions.fileSuffixFilters = ['.txt']; let uris: Array = []; const documentViewPicker = new picker.DocumentViewPicker(); + //Pull up the picker selection file return await documentViewPicker.select(documentSelectOptions).then((documentSelectResult: Array) => { uris = documentSelectResult; let uri: string = uris[0]; let path: string = new fileUri.FileUri(uri).path; Logger.info(`Open The File path is [${uri}]`); let file = fs.openSync(path, fs.OpenMode.WRITE_ONLY); + //Call the native method to write a file let res = FileAccess.writeFileUsingPickerFd(file.fd, contents); fs.closeSync(file.fd); return res; @@ -51,12 +57,14 @@ async function WriteFileByPicker(contents: string): Promise { return 'Write Failed by Picker'; }) } - +// [End by_pick] +// [Start fun_read_pick] async function ReadFileByPicker(): Promise { + //Configure picker Selection Information const documentSelectOptions = new picker.DocumentSelectOptions(); documentSelectOptions.maxSelectNumber = 1; documentSelectOptions.fileSuffixFilters = ['.txt']; - + //Pull up the picker selection file let uris: Array = []; const documentViewPicker = new picker.DocumentViewPicker(); return await documentViewPicker.select(documentSelectOptions).then((documentSelectResult: Array) => { @@ -65,6 +73,7 @@ async function ReadFileByPicker(): Promise { let path: string = new fileUri.FileUri(uri).path; Logger.info(`The Opened File path is [${uri}]`); let file = fs.openSync(path, fs.OpenMode.READ_ONLY); + //Call the native method to read the file. let res = FileAccess.readFileUsingPickerFd(file.fd); fs.closeSync(file.fd); return res; @@ -73,7 +82,7 @@ async function ReadFileByPicker(): Promise { return 'Read Failed by Picker!'; }) } - +// [End fun_read_pick] export { CreateFileByPicker, WriteFileByPicker, ReadFileByPicker }; \ No newline at end of file diff --git a/entry/src/main/ets/pages/Index.ets b/entry/src/main/ets/pages/Index.ets index 4fb607cec4c42a3bf3366cf2aabff1732b44f201..971cdd3644e53a0df9fca73f7f6f591f517c63a2 100644 --- a/entry/src/main/ets/pages/Index.ets +++ b/entry/src/main/ets/pages/Index.ets @@ -12,11 +12,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +/** + * 最佳实践:Native侧实现文件访问开发实践 + */ import { promptAction } from '@kit.ArkUI'; import { resourceManager } from '@kit.LocalizationKit'; import { BusinessError } from '@kit.BasicServicesKit'; +// [Start file_access] +// [Start file_access_so] +// [Start file_access_so1] import FileAccess from 'libfile_access.so'; +// [End file_access_so1] +// [End file_access_so] +// [End file_access] import readFile from '../common/utils/ReadFile'; import Logger from '../common/utils/Logger'; import { CreateFileByPicker, WriteFileByPicker, ReadFileByPicker } from '../common/utils/FileOperate'; @@ -25,9 +33,12 @@ import { FileNameList } from '../model/FileNameModel'; @Entry @Component struct Index { - private sandboxFilesDir: string = getContext(this).filesDir; - private resMgr: resourceManager.ResourceManager = getContext().resourceManager; - + // [Start sand_box] + private sandboxFilesDir: string = this.getUIContext().getHostContext()!.filesDir; + // [End sand_box] + // [Start resMgr] + private resMgr: resourceManager.ResourceManager = this.getUIContext().getHostContext()!.resourceManager; + // [End resMgr] @Styles customButtonStyle() { .width('288vp') @@ -37,7 +48,7 @@ struct Index { customToast(str: string) { Logger.info('show file contents:' + str); try { - promptAction.showToast({ + this.getUIContext().getPromptAction().showToast({ message: str, duration: 2000, bottom: '80vp', @@ -56,38 +67,44 @@ struct Index { Button($r('app.string.button_sandbox')) .customButtonStyle() .onClick(() => { - let content = getContext(this).resourceManager + let content = this.getUIContext().getHostContext()!.resourceManager .getStringSync($r('app.string.file_content_sandbox')); + // [Start trans_box_path] FileAccess.transferSandboxPath(this.sandboxFilesDir, content); + // [End trans_box_path] this.customToast(readFile(this.sandboxFilesDir + '/' + FileNameList[0])); }) Button($r('app.string.button_splice')) .customButtonStyle() .onClick(() => { - let content = getContext(this).resourceManager + let content = this.getUIContext().getHostContext()!.resourceManager .getStringSync($r('app.string.file_content_splice')); + // [Start file_path] FileAccess.splicePath(content); + // [End file_path] this.customToast(readFile(this.sandboxFilesDir + '/' + FileNameList[1])); }) Button($r('app.string.button_resMgr')) .customButtonStyle() .onClick(() => { + // [Start raw_file_con] let rawfileContext = FileAccess.transferResourceMgr(this.resMgr, FileNameList[2]); + // [End raw_file_con] this.customToast(rawfileContext.toString()); }) Button($r('app.string.button_create')) .customButtonStyle() .onClick(async () => { - CreateFileByPicker(getContext(this), FileNameList[3]); + CreateFileByPicker(this.getUIContext().getHostContext()!, FileNameList[3]); }) Button($r('app.string.button_write')) .customButtonStyle() .onClick(async () => { - let content = getContext(this).resourceManager + let content = this.getUIContext().getHostContext()!.resourceManager .getStringSync($r('app.string.file_content_picker')); await WriteFileByPicker(content).then((value: string) => { setTimeout(() => {