鸿蒙 Core File Kit(文件基础服务)之简单使用文件

news2025/5/14 13:38:35

查看常用的沙箱目录

在这里插入图片描述
应用沙箱文件访问关系图


在这里插入图片描述
应用文件目录结构图


查看常用的沙箱目录

@Entry
@Component
struct Index {
  build() {
    Button('查看常用的沙箱目录').onClick(_=>{
      let ctx = getContext() // UI下只能使用这个方法,不能 this.context

      console.log('--应用缓存文件保存目录:', ctx.cacheDir)
      // --应用缓存文件保存目录: /data/storage/el2/base/haps/entry/cache

      console.log('--应用临时文件保存目录:', ctx.tempDir)
      // --应用临时文件保存目录: /data/storage/el2/base/haps/entry/temp

      console.log('--应用普通文件保存目录:', ctx.filesDir)
      // --应用普通文件保存目录: /data/storage/el2/base/haps/entry/files

      console.log('--应用数据库文件保存目录:', ctx.databaseDir)
      // --应用数据库文件保存目录: /data/storage/el2/database/entry

      console.log('--应用首选项文件保存目录:', ctx.preferencesDir)
      // --应用首选项文件保存目录: /data/storage/el2/base/haps/entry/preferences

      console.log('--应用分布式共享文件保存目录:', ctx.distributedFilesDir)
      //   --应用分布式共享文件保存目录: /data/storage/el2/distributedfiles
    })
  }
}

DevEco Studio 开发工具右下角有个 Device File Browser,模拟器跑应用的前提下,查看真实的物理目录

data->app->el2->100->base->(项目的 bundleName)->haps->entry(模块名)->files

基础文件操作接口功能

使用 @kit.CoreFileKit 这个 IO 接口

函数名功能描述函数名功能描述
access()检查文件是否存在rmdir()删除整个目录
close()关闭文件stat()获取文件详细属性信息
copyFile()复制文件unlink()删除单个文件
createStream()打开文件流write()将数据写入文件
listFile()列出文件夹下所有文件Stream.close()关闭文件流
mkdir()创建目录Stream.flush()刷新文件流/冲刷缓冲区
moveFile()移动文件Stream.write()将数据写入流文件
open()打开文件Stream.read()从流文件读取数据
read()从文件读取数据File.fd获取文件描述符
rename()重命名文件OpenMode设置文件打开标签

| 是按位或运算符,用于合并多个互不冲突的选项(标志位),在文件操作中常用于灵活组合打开模式

下面的示例代码注意需要引入的模块,button 组件就看着放就好

写入

Button("2.向应用文件中写出内容 —— 写出日志").onClick(async (_) => {
  // 获取应用上下文对象(参考表格外的框架接口)
  let ctx = getContext();

  // 获取应用沙箱文件目录路径(filesDir为系统预定义路径)
  let dir = ctx.filesDir;

  // 拼接完整文件路径:目录 + 文件名(参考表格中的`rename()`路径操作逻辑)
  let path = dir + "/log01.txt";

  // 异步打开文件(对应表格中的`open()`函数)
  // path: 文件路径(必须参数)
  // OpenMode组合参数(按位或):
  // - CREATE: 文件不存在时创建(表格中`mkdir()`的衍生行为)
  // - APPEND: 追加写入(避免覆盖原有内容)
  // - WRITE_ONLY: 只写模式(与表格中的`read()`互补)
  let f = await fileIo.open(
    path,
    fileIo.OpenMode.CREATE | fileIo.OpenMode.APPEND | fileIo.OpenMode.WRITE_ONLY
  );

  // 构造日志内容:时间戳 + 固定标记(Date.now()生成13位Unix时间戳)
  let str = Date.now() + ":" + "best adc";

  // 异步写入文件(对应表格中的`write()`函数)
  // f.fd: 文件描述符(来自表格中的`File.fd`属性,标识操作系统级文件句柄)
  // str: 要写入的字符串数据(二进制数据需用Buffer转换)
  let len = await fileIo.write(f.fd, str);

  // 打印日志:len表示实际写入字节数(表格中`write()`的返回值)
  console.log(
    "--应用文件写出完成,此次写出的数据长度:",
    len,
    "文件沙箱目录:",
    path
  );

  // 关闭文件(对应表格中的`close()`函数,释放系统资源)
  await fileIo.close(f);
});

读取

读取的文件是上个示例创建的 log01.txt

import { buffer } from "@kit.ArkTS";

Button("从应用文件中读取内容 —— 读取日志").onClick(async (_) => {
  //指定文件目录和文件名
  let ctx = getContext();
  let dir = ctx.filesDir;
  let path = dir + "/log01.txt";

  //打开指定文件,以只读方式
  let f = await fileIo.open(path, fileIo.OpenMode.READ_ONLY);

  //读取文件内容,保存在一个缓冲区对象中
  let buf = new ArrayBuffer(1024); //用于保存读取到的数据的缓冲区
  let len = await fileIo.read(f.fd, buf);
  console.log("--文件读取完成,实际读取到的字节数:", len);
  //把缓冲区中的数据转换为字符串,打印到控制台 —— 前提必需保证缓冲区中的数据是字符数据
  let data = buffer.from(buf, 0, len); // 从一个缓冲区对象中构建字符串对象
  console.log("--读取到的内容:", data);

  //关闭文件
  await fileIo.close(f);
});

拷贝

Button("读取并写出应用文件 —— 拷贝日志").onClick(async (_) => {
  //指定读取文件 和 写出文件 路径
  let ctx = getContext();
  let path0 = ctx.filesDir + "/log01.txt"; //源文件——必须存在
  let path1 = ctx.filesDir + "/log02.txt"; //目标文件——必须不存在

  //打开两个文件
  let f0 = await fileIo.open(path0, fileIo.OpenMode.READ_ONLY);
  let f1 = await fileIo.open(
    path1,
    fileIo.OpenMode.CREATE | fileIo.OpenMode.TRUNC | fileIo.OpenMode.WRITE_ONLY
  ); //如果不存在就创建,否则截断(truncate)已有内容

  //从源文件中读取数据,暂放在缓冲区中,写出到目标文件中
  let buf = new ArrayBuffer(32); //用于暂存此次读取的数据
  let len = 0; //此次实际读取到的字节数

  let total = 0; //拷贝的总字节数
  while ((len = await fileIo.read(f0.fd, buf)) > 0) {
    total += len;
    await fileIo.write(f1.fd, buf, { length: len }); //只把缓冲区中指定长度的数据写出
  }
  console.log("--文件拷贝完成,拷贝的总字节数:", total);

  //关闭两个文件
  await fileIo.close(f0);
  await fileIo.close(f1);
});

选择用户文件

用户有时需要分享或保存图片、视频等用户文件,开发者可以通过系统预置的文件选择器模块来实现(ohos.file.picker);根据用户文件的常见类型,选择器模块分别提供以下接口:

  • PhotoViewPicker:适用于图片或视频类型文件的选择与保存——图库中的资源;
import { photoAccessHelper } from "@kit.MediaLibraryKit"; //API12
const photoViewPicker = new photoAccessHelper.PhotoViewPicker();
photoViewPicker.select(); //拉起图库界面选择文件
  • DocumentViewPicker:适用于文件类型文件的选择与保存——如浏览器下载的文档等;
import { picker } from "@kit.CoreFileKit";
const documentViewPicker = new picker.DocumentViewPicker();
documentViewPicker.select(); //拉起文件选择界面
  • AudioViewPicker:适用于音频类型文件的选择与保存。
import { picker } from "@kit.CoreFileKit";
const audioViewPicker = new picker.AudioViewPicker();
audioViewPicker.select(); //拉起文件选择界面

选择用户文件–选择图片

import { photoAccessHelper } from "@kit.MediaLibraryKit";

Button("读取用户文件 —— 读取图库中的图片并显式").onClick(async (_) => {
  //拉起图片文件拾取窗口,让用户选择文件(本质就是授权应用访问用户文件)
  let pvp = new photoAccessHelper.PhotoViewPicker();
  // let result = await pvp.select()
  let result = await pvp.select({
    maxSelectNumber: 1, //一次最多可以选择多少个文件
    MIMEType: photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE, //限定此次只能选择图片文件,不能选择视频文件
  });
  // console.log('--图片查看拾取器选择的结果:', JSON.stringify(result))
  let uri = result.photoUris[0];
  console.log("--用户选中的第0个图片的虚拟地址:", uri);
  //此后就可以使用fileIo.open(uri)进行文件的读取/拷贝....
  this.imgSrc = uri; //还可以直接作为Image的来源进行显式
});

Image(this.imgSrc).width("80%");

选择图库中的图片并上传

import { photoAccessHelper } from '@kit.MediaLibraryKit'
import { fileIo } from '@kit.CoreFileKit'
import axios, { AxiosResponse, FormData } from '@ohos/axios'

@Entry
@Component
struct Index {
  build() {
    Button('读取用户文件 —— 选择图库中的图片并上传').onClick(async _=>{
      //拉起图片文件选择器,让用户选择一张图片
      let pvp = new photoAccessHelper.PhotoViewPicker()
      let result = await pvp.select({
        maxSelectNumber: 1,
        MIMEType:photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE
      })
      let path = result.photoUris[0]
      console.log('--用户选中的图库文件虚拟路径:', path)

      //读取指定路径的文件内容,保存入一个缓冲区
      let f = await fileIo.open(path, fileIo.OpenMode.READ_ONLY)
      let stat = await fileIo.stat(f.fd) //获取文件的各项统计信息
      let size = stat.size    //文件大小
      let buf = new ArrayBuffer(size)   //创建一个与文件大小一样的内存缓冲区对象,用于盛放文件内容
      let len = await fileIo.read(f.fd, buf)  //读取文件内容
      await fileIo.close(f)
      console.log('--文件读取完成:',size, len)

      //把缓冲区中的数据封装为Multipart/Form-Data格式的请求主体
      let body = new FormData()
      body.append('avatar', buf)

      //使用Axios把请求主体提交给服务器API
      let url = 'https://www.**你懂的**.com'
      let res: AxiosResponse = await axios({
        method:'POST',
        url,
        headers: {
          'Content-Type': 'multipart/form-data',
          'token': '加入你自己的token'
        },
        data: body
      })
      console.log('--服务器端请求执行完成,响应消息主体数据:', JSON.stringify(res.data))
    })
  }
}

保存用户文件

在从网络下载文件到本地、或将已有用户文件另存为新的文件路径等场景下,需要使用 ohos.fs.picker 模块提供的保存用户文件的能力。

  • 保存图片或视频类型文件:

    import { picker } from "@kit.CoreFileKit";
    const photoViewPicker = new picker.PhotoViewPicker();
    photoViewPicker.save(); //拉起文件选择界面选择文件夹
    
  • 保存文档类文件:

    import { picker } from "@kit.CoreFileKit";
    const documentViewPicker = new picker.DocumentViewPicker();
    documentViewPicker.save(); //拉起文件选择界面选择文件夹
    
  • 保存音频类文件:

    import { picker } from "@kit.CoreFileKit";
    const audioViewPicker = new picker.AudioViewPicker();
    audioViewPicker.save(); //拉起文件选择界面选择文件夹
    

保存用户文件-网络下载图片

module.json5 文件中声明 网络权限

"module": {
  "requestPermissions": [   //向系统申请“互联网访问”权限
      {"name": "ohos.permission.INTERNET"}
    ],
}

安装 axios , ohpm install @ohos/axios

import { fileIo, picker } from "@kit.CoreFileKit";
import axios, { AxiosResponse } from "@ohos/axios";

Button("7.读取用户目录 —— 下载文件到该目录").onClick(async (_) => {
  //使用axios请求远程服务器上的图片
  let res: AxiosResponse = await axios({
    method: "GET",
    url: "https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png",
  });
  console.log(
    "--下载图片保存到一个缓冲区对象了: res.data",
    JSON.stringify(res)
  );

  // 拉起文档查看拾取器,选择一个目录用于保存上述文件
  let dvp = new picker.DocumentViewPicker();
  let result = await dvp.save();
  console.log("--文档拾取器选择的目录:", JSON.stringify(result));
  let path = result[0]; //往哪个文件中写出下载的图片内容

  //往上述目录下写出下载得到的文件数据
  let f = await fileIo.open(
    path,
    fileIo.OpenMode.CREATE | fileIo.OpenMode.TRUNC | fileIo.OpenMode.WRITE_ONLY
  );
  let len = await fileIo.write(f.fd, res.data);
  console.log("--文件保存完成,总大小:", len);
  await fileIo.close(f);
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2375421.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Qt的app开发第七天

写在前面 笔者是大一下计科生,标题这个项目是笔者这个学期的课设,与学长共创,我负责客户端部分,现在已经实现了待办板块的新建、修改。 这个项目目前已经走上正轨了,博主也实现了主要功能的从无到有&#xff…

目标检测任务常用脚本1——将YOLO格式的数据集转换成VOC格式的数据集

在目标检测任务中,不同框架使用的标注格式各不相同。常见的框架中,YOLO 使用 .txt 文件进行标注,而 PASCAL VOC 则使用 .xml 文件。如果你需要将一个 YOLO 格式的数据集转换为 VOC 格式以便适配其他模型,本文提供了一个结构清晰、…

NLTK库: 数据集3-分类与标注语料(Categorized and Tagged Corpora)

NLTK库: 数据集3-分类与标注语料(Categorized and Tagged Corpora) 1.二分类语料 主要是电影语料,和情绪(积极消极、主观客观)有关,有以下2个语料: 1.1 movie_reviews: IMDb 影评 IMDb(Internet Movie …

uni-app学习笔记五-vue3响应式基础

一.使用ref定义响应式变量 在组合式 API 中&#xff0c;推荐使用 ref() 函数来声明响应式状态&#xff0c;ref() 接收参数&#xff0c;并将其包裹在一个带有 .value 属性的 ref 对象中返回 示例代码&#xff1a; <template> <view>{{ num1 }}</view><vi…

ElasticSeach快速上手笔记-入门篇

由来 Elasticsearch 是一个基于 Apache Lucene 构建的分布式、高扩展、近实时的搜索与数据分析引擎&#xff0c;能够高效处理结构化和非结构化数据的全文检索及复杂分析 搜索&#xff0c;即用户在平台如百度进行输入关键词&#xff0c;由后端给出搜索结果数据进行返回&#x…

《ffplay 读线程与解码线程分析:从初始化到 seek 操作,对比视频与音频解码的差异》

1 read-thread 1.1 初始化部分 1.分配. avformat_alloc_context 创建上下⽂ ic avformat_alloc_context();if (!ic) {av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");ret AVERROR(ENOMEM);goto fail;}2 ic->interrupt_callback.callback deco…

MySQL推荐书单:从入门到精通

给大家介绍一些 MySQL 从入门到精通的经典书单&#xff0c;可以基于不同学习阶段的需求进行选择。 入门 MySQL必知必会 这本书继承了《SQL必知必会》的优点&#xff0c;专门针对 MySQL 用户&#xff0c;没有过多阐述数据库基础理论&#xff0c;而是紧贴实战&#xff0c;直接从…

【Nacos】env NACOS_AUTH_TOKEN must be set with Base64 String.

【Nacos】env NACOS_AUTH_TOKEN must be set with Base64 String. 问题描述 env NACOS_AUTH_TOKEN must be set with Base64 String.原因分析 从错误日志中可以看出&#xff0c;Nacos 启动失败的原因是缺少必要的环境变量 NACOS_AUTH_TOKEN。 NACOS_AUTH_TOKEN: Nacos 用于生…

秋招准备——2.跨时钟相关

格雷码异步FIFO跨时钟域处理 格雷码 一、格雷码规律 相邻性&#xff1a;相邻两个数的格雷码只有一位不同&#xff0c;例如&#xff1a; 0000 → 0001&#xff08;仅最低位变化&#xff09;0001 → 0011&#xff08;仅次低位变化&#xff09;0011 → 0010&#xff08;仅最低位…

激光打印机常见打印故障简单处理意见

一、 问题描述&#xff1a; 给打印机更换新的硒鼓时拉开硒鼓封条时有微量碳粉带出&#xff1b; 原因&#xff1a; 出厂打印测试时&#xff0c;可能会有微量碳粉在磁辊上或者磁辊仓&#xff1b; 解决方法&#xff1a; 擦干净即可正常使用&#xff1b; 二、 问题描述&…

【2025最新】Windows系统装VSCode搭建C/C++开发环境(附带所有安装包)

文章目录 为什么选择VSCode作为C/C开发工具&#xff1f;一、VSCode安装过程&#xff08;超简单&#xff01;&#xff09;二、VSCode中文界面设置&#xff08;再也不用对着英文发愁&#xff01;&#xff09;三、安装C/C插件&#xff08;编程必备神器&#xff01;&#xff09;四、…

MYSQL 查询去除小数位后多余的0

MYSQL 查询去除小数位后多余的0 在MySQL中&#xff0c;有时候我们需要去除存储在数据库中的数字字段小数点后面多余的0。这种情况通常发生在处理金额或其他需要精确小数位的数据时。例如&#xff0c;数据库中存储的是decimal (18,6)类型的数据&#xff0c;但在页面展示时不希望…

基于GF域的多进制QC-LDPC误码率matlab仿真,译码采用EMS算法

目录 1.算法仿真效果 2.算法涉及理论知识概要 3.MATLAB核心程序 4.完整算法代码文件获得 1.算法仿真效果 matlab2022a仿真结果如下&#xff08;完整代码运行后无水印&#xff09;&#xff1a; 本课题实现的是四进制QC-LDPC 仿真操作步骤可参考程序配套的操作视频。 2.算…

Vitrualbox完美显示系统界面(只需三步)

目录 1.使用vitrualbox的增强功能&#xff1a;​编辑 2.安装增强功能&#xff08;安装完后要重启虚拟机&#xff09;&#xff1a; 3. 调整界面尺寸&#xff08;如果一个选项不行的话&#xff0c;就多试试其他不同的百分比&#xff09;&#xff1a; 先看看原来的&#xff0c;…

王炸组合!STL-VMD二次分解 + Informer-LSTM 并行预测模型

往期精彩内容&#xff1a; 单步预测-风速预测模型代码全家桶-CSDN博客 半天入门&#xff01;锂电池剩余寿命预测&#xff08;Python&#xff09;-CSDN博客 超强预测模型&#xff1a;二次分解-组合预测-CSDN博客 VMD CEEMDAN 二次分解&#xff0c;BiLSTM-Attention预测模型…

n8n 修改或者智能体用文档知识库创建pdf

以下是对 Nextcloud、OnlyOffice、Seafile、Etherpad、BookStack 和 Confluence 等本地部署文档协作工具的综合评测、对比分析和使用推荐&#xff0c;帮助您根据不同需求选择合适的解决方案。 &#x1f9f0; 工具功能对比 工具名称核心功能本地部署支持适用场景优势与劣势Next…

论坛系统(中-1)

软件开发 编写公共代码 定义状态码 对执⾏业务处理逻辑过程中可能出现的成功与失败状态做针对性描述(根据需求分析阶段可以遇见的问题提前做出定义)&#xff0c;⽤枚举定义状态码&#xff0c;先定义⼀部分&#xff0c;业务中遇到新的问题再添加 定义状态码如下 状态码类型描…

FPGA+ESP32 = GameBoy 是你的童年吗?

之前介绍的所有的复古游戏机都是基于Intel-Altera FPGA制作的&#xff0c;今天就带来一款基于AMD-Xilinx FPGA的复古掌上游戏机-Game Bub。 Game Bub是一款掌上游戏机&#xff0c;旨在畅玩 Game Boy、Game Boy Color 和 Game Boy Advance 游戏。与大多数现代掌上游戏机一样&…

3D迷宫探险:伪3D渲染与运动控制的数学重构

目录 3D迷宫探险:伪3D渲染与运动控制的数学重构引言第一章 伪3D渲染引擎1.1 射线投射原理1.2 纹理透视校正第二章 迷宫生成算法2.1 图论生成模型2.2 复杂度控制第三章 第一人称控制3.1 运动微分方程3.2 鼠标视角控制第四章 碰撞检测优化4.1 层级检测体系4.2 滑动响应算法第五章…

【金仓数据库征文】_金仓数据库在金融行业的两地三中心容灾架构实践

金仓数据库在金融行业的两地三中心容灾架构实践 &#x1f31f;嗨&#xff0c;我是LucianaiB&#xff01; &#x1f30d; 总有人间一两风&#xff0c;填我十万八千梦。 &#x1f680; 路漫漫其修远兮&#xff0c;吾将上下而求索。 引言 随着国家对信息技术应用创新&#xff0…