?文章的目的為了記錄使用Arkts?進行Harmony?app?開發學習的經歷。本職為嵌入式軟件開發,公司安排開發app,臨時學習,完成app的開發。開發流程和要點有些記憶模糊,趕緊記錄,防止忘記。
?相關鏈接:
開源 Arkts 鴻蒙應用 開發(一)工程文件分析-CSDN博客
開源 Arkts 鴻蒙應用 開發(二)封裝庫.har制作和應用-CSDN博客
開源 Arkts 鴻蒙應用 開發(三)Arkts的介紹-CSDN博客
開源 Arkts 鴻蒙應用 開發(四)布局和常用控件-CSDN博客
開源 Arkts 鴻蒙應用 開發(五)控件組成和復雜控件-CSDN博客
?推薦鏈接:
開源 java android app 開發(一)開發環境的搭建-CSDN博客
開源 java android app 開發(二)工程文件結構-CSDN博客
開源 java android app 開發(三)GUI界面布局和常用組件-CSDN博客
開源 java android app 開發(四)GUI界面重要組件-CSDN博客
開源 java android app 開發(五)文件和數據庫存儲-CSDN博客
開源 java android app 開發(六)多媒體使用-CSDN博客
開源 java android app 開發(七)通訊之Tcp和Http-CSDN博客
開源 java android app 開發(八)通訊之Mqtt和Ble-CSDN博客
開源 java android app 開發(九)后臺之線程和服務-CSDN博客
開源 java android app 開發(十)廣播機制-CSDN博客
開源 java android app 開發(十一)調試、發布-CSDN博客
開源 java android app 開發(十二)封庫.aar-CSDN博客
推薦鏈接:
開源C# .net mvc 開發(一)WEB搭建_c#部署web程序-CSDN博客
開源 C# .net mvc 開發(二)網站快速搭建_c#網站開發-CSDN博客
開源 C# .net mvc 開發(三)WEB內外網訪問(VS發布、IIS配置網站、花生殼外網穿刺訪問)_c# mvc 域名下不可訪問內網,內網下可以訪問域名-CSDN博客
開源 C# .net mvc 開發(四)工程結構、頁面提交以及顯示_c#工程結構-CSDN博客
開源 C# .net mvc 開發(五)常用代碼快速開發_c# mvc開發-CSDN博客
本章節內容如下:
1.? 文件存儲
2.? 首選項存儲
一、文件讀寫,實現了按鍵將對話框數據對寫入文件,按鍵讀取文件數據到對話框。寫入后,關閉app,重新打開后再讀出,驗證文件存取成功。
1.1? 寫入文件和讀出文件代碼
writeToFile() {try {let file = fs.openSync(this.filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);fs.writeSync(file.fd, this.inputText);fs.closeSync(file.fd);this.outputText = '內容已成功寫入文件';console.log('寫入文件成功');} catch (error) {console.error(`寫入文件失敗: ${error.message}`);this.outputText = '寫入文件失敗';}}readFromFile() {try {if (!fs.accessSync(this.filePath)) {this.outputText = '文件不存在';return;}let file = fs.openSync(this.filePath, fs.OpenMode.READ_ONLY);let stat = fs.statSync(this.filePath);let arrayBuffer = new ArrayBuffer(stat.size);fs.readSync(file.fd, arrayBuffer);fs.closeSync(file.fd);// 使用循環將Uint8Array轉換為字符串const uint8Array = new Uint8Array(arrayBuffer);let result = '';for (let i = 0; i < uint8Array.length; i++) {result += String.fromCharCode(uint8Array[i]);}this.outputText = result;} catch (error) {console.error(`讀取文件失敗: ${error.message}`);this.outputText = '讀取文件失敗';}}
1.2? 界面代碼
build() {Column({ space: 20 }) {TextInput({ placeholder: '請輸入要保存的內容' }).width('90%').height(60).onChange((value: string) => {this.inputText = value;})Button('寫入文件').width('60%').height(40).onClick(() => {this.writeToFile();})TextInput({ placeholder: '文件內容將顯示在這里', text: this.outputText }).width('90%').height(60)Button('讀取文件').width('60%').height(40).onClick(() => {this.readFromFile();})}.width('100%').height('100%').justifyContent(FlexAlign.Center)}
1.3? \pages\index.ets代碼
// MainAbility.ets
import common from '@ohos.app.ability.common';
import fs from '@ohos.file.fs';@Entry
@Component
struct FileReadWriteExample {@State inputText: string = '';@State outputText: string = '';private context = getContext(this) as common.UIAbilityContext;private filePath: string = '';aboutToAppear() {this.filePath = this.context.filesDir + '/example.txt';console.log(`文件路徑: ${this.filePath}`);}writeToFile() {try {let file = fs.openSync(this.filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);fs.writeSync(file.fd, this.inputText);fs.closeSync(file.fd);this.outputText = '內容已成功寫入文件';console.log('寫入文件成功');} catch (error) {console.error(`寫入文件失敗: ${error.message}`);this.outputText = '寫入文件失敗';}}readFromFile() {try {if (!fs.accessSync(this.filePath)) {this.outputText = '文件不存在';return;}let file = fs.openSync(this.filePath, fs.OpenMode.READ_ONLY);let stat = fs.statSync(this.filePath);let arrayBuffer = new ArrayBuffer(stat.size);fs.readSync(file.fd, arrayBuffer);fs.closeSync(file.fd);// 使用循環將Uint8Array轉換為字符串const uint8Array = new Uint8Array(arrayBuffer);let result = '';for (let i = 0; i < uint8Array.length; i++) {result += String.fromCharCode(uint8Array[i]);}this.outputText = result;} catch (error) {console.error(`讀取文件失敗: ${error.message}`);this.outputText = '讀取文件失敗';}}build() {Column({ space: 20 }) {TextInput({ placeholder: '請輸入要保存的內容' }).width('90%').height(60).onChange((value: string) => {this.inputText = value;})Button('寫入文件').width('60%').height(40).onClick(() => {this.writeToFile();})TextInput({ placeholder: '文件內容將顯示在這里', text: this.outputText }).width('90%').height(60)Button('讀取文件').width('60%').height(40).onClick(() => {this.readFromFile();})}.width('100%').height('100%').justifyContent(FlexAlign.Center)}
}
1.4? 演示
二、首選項讀寫
2.1? 頁面顯示代碼index.ets,實現顯示3個按鈕。
// index.ets
@Entry
@Component
struct Index {build() {Column() {Button('Button 1').margin({ top: 10, bottom: 10 }).onClick(() => {// 通過全局對象調用Ability方法if (globalThis.entryAbility?.btn1) {globalThis.entryAbility.btn1();}}).width('100%')Row()Button('Button 2').margin({ top: 10, bottom: 10 }).onClick(() => {if (globalThis.entryAbility?.btn2) {globalThis.entryAbility.btn2();}}).width('100%')Button('Button 3').margin({ top: 10, bottom: 10 }).onClick(() => {if (globalThis.entryAbility?.btn3) {globalThis.entryAbility.btn3();}}).width('100%')}.width('100%').height('100%')}
}
2.2? UIAbility的代碼EntryAbility.ets,功能包括
初始化Preferences數據存儲
提供三個按鈕操作:
btn1(): 寫入字符串、二進制數據和數字到Preferences
btn2(): 從Preferences讀取并顯示存儲的數據
btn3(): 刪除Preferences中的數據
Preferences操作
代碼中提供了完整的Preferences CRUD操作:
初始化:initPreferences()異步方法
寫入數據:btn1()使用putSync()同步寫入三種類型數據、字符串、二進制數據(Uint8Array)、數字
讀取數據:btn2()使用getSync()同步讀取數據、使用TextDecoder解碼二進制數據
刪除數據:btn3()使用deleteSync()同步刪除數據
Preferences同步/異步操作:
初始化使用異步getPreferences()
數據操作使用同步方法(putSync, getSync, deleteSync)
寫入后調用flushSync()確保數據持久化
以下為代碼
import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';import { BusinessError } from '@kit.BasicServicesKit';import { preferences } from '@kit.ArkData';
import { util } from '@kit.ArkTS';const DOMAIN = 0x0000;
let dataPreferences: preferences.Preferences | null = null;export default class EntryAbility extends UIAbility {// 初始化Preferencesasync initPreferences(): Promise<void> {try {let options: preferences.Options = { name: 'myStore' };dataPreferences = await preferences.getPreferences(this.context, options);} catch (err) {hilog.error(DOMAIN, 'testTag', 'Failed to get preferences. Cause: %{public}s', JSON.stringify(err));}}// 按鈕1:寫入數據btn1(): void {if (!dataPreferences) {console.error('click btn1 Preferences not initialized');return;}try {// 寫入字符串dataPreferences.putSync('string_key', 'Hello ArkTS');// 寫入Uint8Arraylet encoder = new util.TextEncoder();let uInt8Array = encoder.encodeInto("你好,ArkTS");dataPreferences.putSync('binary_key', uInt8Array);// 寫入數字dataPreferences.putSync('number_key', 123);dataPreferences.flushSync();console.info('click btn1 Preferences Data written successfully');} catch (err) {console.error('click btn1 Preferences Failed to write data: ' + JSON.stringify(err));}}// 按鈕2:讀取數據btn2(): void {if (!dataPreferences) {console.error('click btn2 Preferences not initialized');return;}try {// 讀取字符串let stringVal = dataPreferences.getSync('string_key', 'default');console.info('click btn2 Preferences String value: ' + stringVal);// 讀取二進制數據let binaryVal = dataPreferences.getSync('binary_key', new Uint8Array(0));let decoder = new util.TextDecoder('utf-8');let decodedStr = decoder.decode(binaryVal as Uint8Array);console.info('click btn2 Preferences Binary value: ' + decodedStr);// 讀取數字let numberVal = dataPreferences.getSync('number_key', 0);console.info('click btn2 Preferences Number value: ' + numberVal);} catch (err) {console.error('click btn2 Preferences Failed to read data: ' + JSON.stringify(err));}}// 按鈕3:刪除數據btn3(): void {if (!dataPreferences) {console.error('click btn3 Preferences not initialized');return;}try {dataPreferences.deleteSync('string_key');dataPreferences.deleteSync('binary_key');dataPreferences.deleteSync('number_key');console.info('click btn3 Preferences Data deleted successfully');} catch (err) {console.error('click btn3 Preferences Failed to delete data: ' + JSON.stringify(err));}}onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');globalThis.abilityContext = this.context;globalThis.entryAbility = this;// 初始化Preferencesthis.initPreferences();}onWindowStageCreate(windowStage: window.WindowStage): void {// Main window is created, set main page for this abilityhilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');windowStage.loadContent('pages/Index', (err) => {if (err.code) {hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));return;}hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');});/*let options: preferences.Options = { name: 'myStore' };dataPreferences = preferences.getPreferencesSync(this.context, options);if (dataPreferences.hasSync('startup')) {console.info("The key 'startup' is contained.");} else {console.info("The key 'startup' does not contain.");// 此處以此鍵值對不存在時寫入數據為例dataPreferences.putSync('startup', 'auto');// 當字符串有特殊字符時,需要將字符串轉為Uint8Array類型再存儲,長度均不超過16 * 1024 * 1024個字節。//let uInt8Array1 = new util.TextEncoder().encodeInto("~!@#¥%……&*()——+?");let encoder: util.TextEncoder = new util.TextEncoder();let uInt8Array1: Uint8Array = encoder.encodeInto("你好,ArkTS"); // 或 encode()dataPreferences.putSync('uInt8', uInt8Array1);}let val = dataPreferences.getSync('startup', 'default');console.info("The 'startup' value is " + val);// 當獲取的值為帶有特殊字符的字符串時,需要將獲取到的Uint8Array轉換為字符串let uInt8Array2 : preferences.ValueType = dataPreferences.getSync('uInt8', new Uint8Array(0));let textDecoder = util.TextDecoder.create('utf-8');val = textDecoder.decodeToString(uInt8Array2 as Uint8Array);console.info("The 'uInt8' value is " + val);*/}onWindowStageDestroy(): void {// Main window is destroyed, release UI related resourceshilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');}onForeground(): void {// Ability has brought to foregroundhilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');}onBackground(): void {// Ability has back to backgroundhilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');}
}
2.3? 測試效果如下,測試了寫入,讀出,刪除。刪除后再讀出則為空。