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

查看常用的沙箱目录

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


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


查看常用的沙箱目录

@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);
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值