第十九天 HarmonyOS的文件操作和本地存储
一、前言:为什么需要掌握文件操作与本地存储?
在移动应用开发中,文件操作和本地存储是每个开发者都必须掌握的核心技能。无论是保存用户配置、缓存网络数据,还是处理图片/视频等多媒体文件,都需要通过文件系统进行操作。在HarmonyOS开发中,系统提供了完善的API体系和沙箱安全机制,帮助开发者实现安全高效的本地存储。
二、HarmonyOS文件系统基础
2.1 沙箱机制解析
HarmonyOS为每个应用分配独立的存储空间,采用沙箱机制隔离不同应用的数据。通过实际路径对比理解这个机制:
// 应用私有目录路径示例
context.getFilesDir() → /data/app/el2/100/base/com.example.demo/haps/entry/files
2.2 存储区域划分
| 存储类型 | 访问权限 | 清除策略 |
|---|---|---|
| 应用私有目录 | 仅本应用可读写 | 卸载自动清除 |
| 公共目录 | 需申请权限 | 持久保存 |
| 缓存目录 | 自动管理 | 空间不足时清除 |
三、四大本地存储方案实战
3.1 应用私有文件操作(基础版)
完整文件读写示例:
// 获取文件目录
File filesDir = getContext().getFilesDir();// 写入文件
try (FileOutputStream fos = new FileOutputStream(new File(filesDir, "config.txt"))) {fos.write("Hello HarmonyOS".getBytes());
} catch (IOException e) {HiLog.error(LABEL, "文件写入失败: " + e.getMessage());
}// 读取文件
StringBuilder content = new StringBuilder();
try (BufferedReader br = new BufferedReader(new FileReader(new File(filesDir, "config.txt")))) {String line;while ((line = br.readLine()) != null) {content.append(line);}
} catch (IOException e) {HiLog.error(LABEL, "文件读取失败: " + e.getMessage());
}
3.2 Preferences轻量存储
键值对存储最佳实践:
// 初始化Preferences实例
Preferences preferences = Preferences.getGlobalPreferences(context);// 存储数据
preferences.putString("userName", "Harmony开发者").putInt("loginCount", 5).flush(); // 立即提交// 读取数据
String name = preferences.getString("userName", "默认值");
int count = preferences.getInt("loginCount", 0);// 监听数据变化
preferences.registerObserver((key) -> {if ("themeMode".equals(key)) {updateTheme(preferences.getString(key, "light"));}
});
3.3 关系型数据库(RelationalStore)
数据库操作四部曲:
步骤1:定义实体类
@Entity
public class User {@PrimaryKeyprivate Integer id;@ColumnInfo(name = "user_name")private String name;// Getter/Setter省略...
}
步骤2:创建数据库
@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends HarmonyOSOpenHelper {private static final String DB_NAME = "user_db";public AppDatabase(Context context) {super(context, DB_NAME, null);}
}
步骤3:实现DAO接口
@Dao
public interface UserDao {@Insertvoid insertUser(User user);@Query("SELECT * FROM User WHERE id = :userId")User getUserById(int userId);
}
步骤4:业务层调用
UserDao userDao = DatabaseHolder.getDatabase().userDao();
userDao.insertUser(new User(1, "张三"));User user = userDao.getUserById(1);
HiLog.info(LABEL, "查询结果:" + user.getName());
3.4 对象存储(ObjectStore)
复杂对象存储方案:
// 创建对象存储
ObjectStore objectStore = ObjectStore.create(context, "MyObjectStore");// 存储自定义对象
User user = new User("李四", 25);
objectStore.put("current_user", user);// 读取对象
User cachedUser = objectStore.get("current_user", User.class);
四、综合实战:备忘录应用开发
4.1 项目结构设计
src/main/java/
├── entry
│ ├── MainAbility.java # 主界面
│ ├── Note.java # 笔记实体类
│ ├── NoteDatabase.java # 数据库类
│ └── NoteDao.java # 数据操作接口
resources/
└── config.json # 配置文件
4.2 核心功能实现
笔记保存功能:
public void saveNote(String title, String content) {Note newNote = new Note();newNote.setTitle(title);newNote.setContent(content);newNote.setCreateTime(new Date());// 同时保存到数据库和本地文件noteDao.insert(newNote);saveToFile(title + ".txt", content);
}private void saveToFile(String fileName, String content) {File targetFile = new File(getExternalFilesDir("notes"), fileName);try (FileWriter writer = new FileWriter(targetFile)) {writer.write(content);} catch (IOException e) {HiLog.error(LABEL, "文件保存失败:" + e.getMessage());}
}
笔记列表展示:
ListContainer listContainer = (ListContainer) findComponentById(ResourceTable.Id_note_list);
List<Note> notes = noteDao.getAllNotes();SampleItemProvider provider = new SampleItemProvider(notes, this);
listContainer.setItemProvider(provider);
五、高级技巧与优化策略
5.1 大文件分块传输
private static final int BUFFER_SIZE = 1024 * 1024; // 1MB缓冲区void copyLargeFile(File source, File target) throws IOException {try (InputStream is = new FileInputStream(source);OutputStream os = new FileOutputStream(target)) {byte[] buffer = new byte[BUFFER_SIZE];int bytesRead;while ((bytesRead = is.read(buffer)) != -1) {os.write(buffer, 0, bytesRead);updateProgress(bytesRead); // 更新进度条}}
}
5.2 数据库事务优化
noteDatabase.beginTransaction();
try {for (int i = 0; i < 1000; i++) {Note note = generateTestNote(i);noteDao.insert(note);}noteDatabase.setTransactionSuccessful();
} finally {noteDatabase.endTransaction();
}
六、常见问题排查指南
6.1 权限问题处理方案
<!-- config.json添加权限声明 -->
"reqPermissions": [{"name": "ohos.permission.READ_USER_STORAGE","reason": "需要读取用户文件"},{"name": "ohos.permission.WRITE_USER_STORAGE","reason": "需要写入用户文件"}
]
6.2 存储空间监控
FileStat stat = new FileStat();
FileStat.getStat(path, stat);
long freeSpace = stat.blockSize * stat.blocksFree;if (freeSpace < 1024 * 1024 * 100) { // 剩余空间小于100MBshowCleanStorageDialog();
}
七、总结与学习建议
通过本文的学习,你应该已经掌握:
- ✔️ 文件系统的沙箱机制与路径获取
- ✔️ Preferences键值对存储的灵活应用
- ✔️ RelationalStore数据库的CRUD操作
- ✔️ 对象存储的使用场景
- ✔️ 综合项目的开发实践
相关文章:
第十九天 HarmonyOS的文件操作和本地存储
一、前言:为什么需要掌握文件操作与本地存储? 在移动应用开发中,文件操作和本地存储是每个开发者都必须掌握的核心技能。无论是保存用户配置、缓存网络数据,还是处理图片/视频等多媒体文件,都需要通过文件系统进行操作…...
VLM(视觉语言模型)与DeepSeek R1(奖励机制)如何结合
VLM(视觉语言模型)与DeepSeek R1(奖励机制)如何结合 flyfish VLM的传统训练依赖于监督学习(直接拟合问答对),而规则奖励函数通常用于强化学习(通过试错和奖励反馈优化策略…...
FFMPEG编码容错处理解决办法之途径----升级库文件
在qt开发环境下接收网络数据,调用ffmpeg解码播放视频,出现闪屏现象,具体现象可以使用操作系统自带的ffplay播放器播放原始视频流可复现;而使用操作系统自带的mpv播放器播放视频则不会出现闪屏;闪屏时会报Could not fin…...
uniapp h5端和app端 使用 turn.js
前提:添加页后,添加页与当前页会重叠在一起,不知道为什么,没有找到解决办法 1.h5端 <template><view class"container"><view id"flipbook"><view class"page page1">Page 1</view><view class"page pag…...
【idea问题排查技巧】
以下是针对 IDEA 中 日志打标(动态标记) 和 全链路追踪 功能的分步详解,结合具体场景和操作截图说明,帮助快速掌握实战技巧。 一、动态日志打标:不修改代码输出关键信息 1. 断点日志打印(非侵入式打标) 场景:在调试时,需要临时查看某个变量的值,但不想修改代码添加…...
【入门音视频】音视频基础知识
🌈前言🌈 这个系列在我学习过程中,对音视频知识归纳总结的笔记。因为音视频相关讲解非常稀少,所以我希望通过这个音视频系列,跟大家一起学习音视频,希望减少初学者在学习上的压力。同时希望也欢迎指出文章的…...
JMeter性能问题
性能测试中TPS上不去的几种原因 性能测试中TPS上不去的几种原因_tps一直上不去-CSDN博客 网络带宽 连接池 垃圾回收机制 压测脚本 通信连接机制 数据库配置 硬件资源 压测机 业务逻辑 系统架构 CPU过高什么原因 性能问题分析-CPU偏高 - 西瓜汁拌面 - 博客园 US C…...
软考高级信息系统项目管理师笔记-第2章信息技术发展
第2章 信息技术发展 2.1 信息技术及其发展 1、按表现形态的不同,信息技术可分为硬技术(物化技术)与软技术(非物化技术)。前者指各种信息设备及其功 能,如传感器、服务器、智能手机、通信卫星、笔记本电脑。后者指有关信息获取与处理的各种知识、方法 与技能,如语言文字…...
大语言模型(LLM)提示词(Prompt)高阶撰写指南
——结构化思维与工程化实践 一、LLM提示词设计的核心逻辑 1. 本质认知 LLM是「超强模式识别器概率生成器」,提示词的本质是构建数据分布约束,通过语义信号引导模型激活特定知识路径。优秀提示词需实现: 精准性:消除歧义&#…...
捷 C++ 课程学习笔记:STL 应用与复杂度分析
一、STL 六大组件 STL(Standard Template Library)是 C 标准库的重要组成部分,提供了通用的模板类和函数,用于实现常用的数据结构和算法。STL 主要包括以下六大组件: 容器(Containers)…...
【python】提取word\pdf格式内容到txt文件
一、使用pdfminer提取 import os import re from pdfminer.high_level import extract_text import docx2txt import jiebadef read_pdf(file_path):"""读取 PDF 文件内容:param file_path: PDF 文件路径:return: 文件内容文本"""try:text ext…...
数据结构☞泛型
一.基础定义与应用方向 1.定义: 一般的类和方法,只能使用具体的类型 : 要么是基本类型,要么是自定义的类。如果要编写可以 应用于多种类型 的代码,这种刻板的限制对代码的束缚就会很大。----- 来源《 Java 编程思想》对泛型的介…...
MFC学习笔记-1
一、编辑框和按钮 //.h文件private:CString str;//给窗口类加了一个变量(定义一个成员变量),关联到IDC_EDIT1中(要在实现中关联,源文件文件夹中)CString str2;//接收button2,和IDC_EDIT2绑定 p…...
html中rel、href、src、url的区别
1.url url(统一资源定位符):是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。 2.href href:Hypertext Reference的缩写。 意思是超文本引用。 3.rel rel:relatio…...
hot100-二叉树
二叉树 二叉树递归 相当于这个的顺序来回调换 class Solution {private List<Integer> res new ArrayList<>();public List<Integer> inorderTraversal(TreeNode root) {if(root null)return res;inorderTraversal(root.left);res.add(root.val);inorde…...
嵌入式项目:STM32刷卡指纹智能门禁系统
本文详细介绍基于STM32的刷卡指纹智能门禁系统。 获取资料/指导答疑/技术交流/选题/帮助,请点链接: https://gitee.com/zengzhaorong/share_contact/blob/master/stm32.txt 1 系统功能 1.1 功能概述 本系统由STM32硬件端(下位机)…...
短剧小程序系统源码
短剧小程序系统源码 今天我要向大家介绍的是最新作品——短剧小程序系统源码。这不仅仅是一款简单的播放工具,它背后蕴含的强大功能能够帮助你的短剧业务实现质的飞跃! 为什么说这款源码很厉害? 首先,在当今竞争激烈的市场环境…...
鸿蒙5.0实战案例:基于measure实现的文本测量
往期推文全新看点(文中附带全新鸿蒙5.0全栈学习笔录) ✏️ 鸿蒙(HarmonyOS)北向开发知识点记录~ ✏️ 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~ ✏️ 鸿蒙应用开发与鸿蒙系统开发哪个更有前景&#…...
C#中级教程(2)——走进 C# 面向对象编程:从基础到进阶的深度探索
一、为什么选择面向对象编程 在软件开发的演进过程中,随着程序规模和复杂度的不断增加,传统的编程方式逐渐暴露出局限性。面向对象编程应运而生,它就像是一位智慧的组织者,将程序中的功能进行模块化划分。每个模块各司其职&#x…...
基于SpringBoot的“流浪动物救助系统”的设计与实现(源码+数据库+文档+PPT)
基于SpringBoot的“流浪动物救助系统”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能结构图 局部E-R图 系统首页界面 系统…...
基于WebRTC与AI大模型接入EasyRTC:打造轻量级、高实时、强互动的嵌入式音视频解决方案
随着物联网和嵌入式技术的快速发展,嵌入式设备对实时音视频通信的需求日益增长。然而,传统的音视频解决方案往往存在体积庞大、实时性差、互动体验不佳等问题,难以满足嵌入式设备的资源限制和应用场景需求。 针对以上痛点,本文将介…...
Windows - 通过ssh打开带有图形界面的程序 - 一种通过计划任务的曲折实现方式
Windows(奇思妙想) - 通过ssh打开带有图形界面的程序 - 一种通过计划任务的曲折实现方式 前言 Windows启用OpenSSH客户端后就可以通过SSH的方式访问Windows了。但是通过SSH启动的程序: 无法显示图形界面会随着SSH进程的结束而结束 于是想到了一种通过执行“计划…...
应用层的协议-http/https的状态码
1xx:表示临时响应,需要操作者继续操作 2xx:成功,操作被成功接受并处理 3xx:一般是重定向问题 4xx:客户端的问题 5xx:服务端的问题 1xx: 100: 表示服务器收到客户端的第一部分请…...
前端Sass面试题及参考答案
目录 什么是 Sass? Sass 和 CSS 的主要区别是什么? Sass 中如何处理列表? Sass 中如何处理映射(map)? Sass 中如何使用函数? Sass 中如何使用内置函数? Sass 中如何设置默认值? Sass 中的 @function 和 @mixin 有什么区别? Sass 中如何实现模块化? Sass 中…...
python采集京东商品详情API接口系列,json数据示例返回
在Python中采集京东商品详情API接口的数据,你需要与京东开放平台(现已更名为京东联盟开放平台)进行交互。京东开放平台提供了多种API接口,用于访问京东的商品数据、用户数据等。然而,需要注意的是,京东对于…...
RT-Thread+STM32L475VET6——USB鼠标模拟
文章目录 前言一、板载资源二、具体步骤1.配置icm20608传感器2.打开CubeMX进行USB配置3. 配置USB3.1 打开USB驱动3.2 声明USB3.3 剪切stm32xxxx_hal_msp.c中的void HAL_PCD_MspInit(PCD_HandleTypeDef* hpcd)和void HAL_PCD_MspDeInit(PCD_HandleTypeDef* hpcd)函数至board.c3.…...
计算机毕业设计SpringBoot+Vue.js母婴商城(源码+LW文档+PPT+讲解+开题报告)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
Teigha(ODA<Open Design Alliance>_开放设计联盟)——cad c# 二次开发
需将dll库文件与exe文件放同一路径下,运行exe即可执行。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Thread…...
Java 中 HTTP 协议版本使用情况剖析
Java 中 HTTP 协议版本使用情况剖析 一、HTTP/1.1 与 HTTP/2 概述 (一)HTTP/1.1 HTTP/1.1 是广泛应用且成熟的 HTTP 协议版本,它在互联网发展历程中扮演了重要角色。其特点主要包括: 连接方式:默认采用短连接,即每次请求都要建立新的 TCP 连接,请求完成后断开。不过也…...
Zama fhEVM应用:摩根大通旗下 Kinexys 发布概念验证
1. 引言 Zama 全同态加密 (FHE) 技术在摩根大通的 Kinexys(以前称为 Onyx)中成功进行了概念验证。该概念验证是“EPIC 项目:通过链上企业隐私、身份和可组合性推动代币化金融”的一部分,在 Kinexys 数字资产沙盒(以前…...
