1、前言

应用沙箱是一种以安全防护为目的的隔离机制,避免数据受到恶意路径穿越访问。在这种沙箱的保护机制下,应用可见的目录范围即为“应用沙箱目录”。

2、参考文档

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/app-sandbox-directoryhttps://developer.huawei.com/consumer/cn/doc/harmonyos-guides/app-sandbox-directoryhttps://developer.huawei.com/consumer/cn/doc/architecture-guides/tools-v1_2-ts_55-0000002329284124https://developer.huawei.com/consumer/cn/doc/architecture-guides/tools-v1_2-ts_55-0000002329284124https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-fshttps://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-fs

3、核心思路

1.通过 UI 交互触发沙箱内文件 / 文件夹的创建、查看、删除等操作,同步展示路径信息。

2.实现沙箱目录下的文件操作,包括创建文件 / 文件夹、获取文件列表及删除文件 / 目录等功能。

4、核心代码

 /**
   * 获取沙箱目录下的文件列表
   * 功能:读取指定目录下的所有文件名并展示
   */
  async getListFile() {
    // 获取沙箱根目录路径
    let pathDir = this.context.filesDir;
    // 调用文件工具的listFile方法获取文件列表
    fs.listFile(pathDir).then((filenames: Array<string>) => {
      console.info('listFile succeed'); // 打印成功日志
      console.log('file count: ' + filenames.length) // 打印文件数量
      // 如果有文件,通过弹窗展示所有文件名
      if (filenames.length > 0) {
        this.getUIContext().showAlertDialog({ message: filenames.join('\n') })
      } else {
        // 无文件时弹窗提示
        this.getUIContext().showAlertDialog({ message: '没有文件' })
      }
      // 遍历打印所有文件名到控制台
      for (let i = 0; i < filenames.length; i++) {
        console.log('fileName:', filenames[i]);
      }
    }).catch((err: BusinessError) => {
      // 捕获并打印文件列表获取失败的错误信息
      console.error('list file failed with error message: ' + err.message + ', error code: ' + err.code);
    });
  }

  /**
   * 创建沙箱文件
   * 功能:在沙箱目录下创建test.txt文件并写入内容"123123123"
   */
  async createFile() {
    // 拼接文件路径:沙箱目录 + "/test.txt"
    this.createFileStr = this.filesDir + "/" + "test.txt"
    // 打开文件(若不存在则创建,权限为读写)
    const file = await fs.open(this.createFileStr, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE)
    // 向文件写入内容
    fs.write(file.fd, "123123123")
    // 关闭文件描述符(释放资源)
    await fs.close(file.fd);
    // 打印文件创建成功信息及路径
    console.info('文件保存成功,路径:', this.createFileStr);
  }

  /**
   * 创建沙箱子文件夹
   * 功能:在沙箱目录下创建名为"hehe"的文件夹
   */
  async createDir() {
    // 拼接文件夹路径:沙箱目录 + "/hehe"
    const dir = this.filesDir + "/" + "hehe"
    try {
      // 调用mkdir方法创建文件夹
      await fs.mkdir(dir)
    } catch (e) {
      // 捕获并打印文件夹创建失败的错误信息
      console.error('文件夹创建失败:', e);
    }
    // 记录创建的文件夹路径
    this.createDirStr = dir
    // 打印文件夹创建成功信息及路径
    console.info('文件夹创建成功,路径:', dir);
  }

  /**
   * 清空沙箱目录(删除沙箱根目录)
   * 注意:删除根目录可能导致后续操作异常,实际使用中需谨慎
   */
  async deleteDir() {
    try {
      // 删除沙箱根目录
      await fs.rmdir(this.context.filesDir)
      // 重新获取文件列表(刷新显示)
      this.getListFile()
    } catch (e) {
      // 捕获并打印删除失败的错误信息
      console.error('文件删除失败:', e);
    }

  }

  /**
   * 删除test.txt文件
   * 功能:删除之前创建的test.txt文件
   */
  async deleteFile() {
    try {
      // 调用unlink方法删除指定文件
      await fs.unlink(this.createFileStr)
      // 重新获取文件列表(刷新显示)
      this.getListFile()
    } catch (e) {
      // 当文件不存在时弹窗提示
      this.getUIContext().showAlertDialog({ message: "没有该文件" })
      // 打印删除失败的错误信息
      console.error('文件删除失败:', e);
    }
  }

5、运行效果

6、完整代码

Index.ets

import { fileIo as fs } from '@kit.CoreFileKit'
import { BusinessError } from '@kit.BasicServicesKit'


@Entry
@ComponentV2
struct Index {
  // 存储应用沙箱目录路径(@Local标记为组件内部状态变量)
  @Local filesDir: string = ""
  // 存储创建的文件路径
  @Local createFileStr: string = ""
  // 存储创建的文件夹路径
  @Local createDirStr: string = ""
  // 获取组件宿主上下文(用于访问沙箱目录等环境信息)
  context = this.getUIContext().getHostContext()!

  /**
   * 组件生命周期方法:在组件即将显示时调用
   * 作用:初始化获取应用沙箱目录路径
   */
  aboutToAppear(): void {
    // 获取沙箱目录路径并赋值给filesDir
    this.filesDir = this.context?.filesDir
  }

  /**
   * 获取沙箱目录下的文件列表
   * 功能:读取指定目录下的所有文件名并展示
   */
  async getListFile() {
    // 获取沙箱根目录路径
    let pathDir = this.context.filesDir;
    // 调用文件工具的listFile方法获取文件列表
    fs.listFile(pathDir).then((filenames: Array<string>) => {
      console.info('listFile succeed'); // 打印成功日志
      console.log('file count: ' + filenames.length) // 打印文件数量
      // 如果有文件,通过弹窗展示所有文件名
      if (filenames.length > 0) {
        this.getUIContext().showAlertDialog({ message: filenames.join('\n') })
      } else {
        // 无文件时弹窗提示
        this.getUIContext().showAlertDialog({ message: '没有文件' })
      }
      // 遍历打印所有文件名到控制台
      for (let i = 0; i < filenames.length; i++) {
        console.log('fileName:', filenames[i]);
      }
    }).catch((err: BusinessError) => {
      // 捕获并打印文件列表获取失败的错误信息
      console.error('list file failed with error message: ' + err.message + ', error code: ' + err.code);
    });
  }

  /**
   * 创建沙箱文件
   * 功能:在沙箱目录下创建test.txt文件并写入内容"123123123"
   */
  async createFile() {
    // 拼接文件路径:沙箱目录 + "/test.txt"
    this.createFileStr = this.filesDir + "/" + "test.txt"
    // 打开文件(若不存在则创建,权限为读写)
    const file = await fs.open(this.createFileStr, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE)
    // 向文件写入内容
    fs.write(file.fd, "123123123")
    // 关闭文件描述符(释放资源)
    await fs.close(file.fd);
    // 打印文件创建成功信息及路径
    console.info('文件保存成功,路径:', this.createFileStr);
  }

  /**
   * 创建沙箱子文件夹
   * 功能:在沙箱目录下创建名为"hehe"的文件夹
   */
  async createDir() {
    // 拼接文件夹路径:沙箱目录 + "/hehe"
    const dir = this.filesDir + "/" + "hehe"
    try {
      // 调用mkdir方法创建文件夹
      await fs.mkdir(dir)
    } catch (e) {
      // 捕获并打印文件夹创建失败的错误信息
      console.error('文件夹创建失败:', e);
    }
    // 记录创建的文件夹路径
    this.createDirStr = dir
    // 打印文件夹创建成功信息及路径
    console.info('文件夹创建成功,路径:', dir);
  }

  /**
   * 清空沙箱目录(删除沙箱根目录)
   * 注意:删除根目录可能导致后续操作异常,实际使用中需谨慎
   */
  async deleteDir() {
    try {
      // 删除沙箱根目录
      await fs.rmdir(this.context.filesDir)
      // 重新获取文件列表(刷新显示)
      this.getListFile()
    } catch (e) {
      // 捕获并打印删除失败的错误信息
      console.error('文件删除失败:', e);
    }

  }

  /**
   * 删除test.txt文件
   * 功能:删除之前创建的test.txt文件
   */
  async deleteFile() {
    try {
      // 调用unlink方法删除指定文件
      await fs.unlink(this.createFileStr)
      // 重新获取文件列表(刷新显示)
      this.getListFile()
    } catch (e) {
      // 当文件不存在时弹窗提示
      this.getUIContext().showAlertDialog({ message: "没有该文件" })
      // 打印删除失败的错误信息
      console.error('文件删除失败:', e);
    }
  }

  /**
   * 构建组件UI界面
   * 布局:垂直排列的文本和按钮,居中显示
   */
  build() {
    Column({ space: 10 }) { // 垂直布局,子元素间距为10
      Text("获取沙箱目录路径🙂") // 显示提示文本
      Text(this.filesDir) // 显示沙箱目录路径

      Text(this.createFileStr) // 显示创建的文件路径
      Button("创建沙箱文件😄")  // 创建文件按钮
        .onClick(() => {
          this.createFile() // 点击触发创建文件方法
        })
      Text(this.createDirStr) // 显示创建的文件夹路径
      Button("创建沙箱子文件夹👏")  // 创建文件夹按钮
        .onClick(() => {
          this.createDir() // 点击触发创建文件夹方法
        })
      Button("获取沙箱目录文件😎")  // 获取文件列表按钮
        .onClick(() => {
          this.getListFile() // 点击触发获取文件列表方法
        })
      Button("清空沙箱文件👍")  // 清空沙箱目录按钮
        .onClick(() => {
          this.deleteDir() // 点击触发删除目录方法
        })

      Button("删除test.txt沙箱文件🤭")  // 删除test.txt文件按钮
        .onClick(() => {
          this.deleteFile() // 点击触发删除文件方法
        })


    }
    .height("100%") // 高度占满父容器
    .width("100%") // 宽度占满父容器
    .justifyContent(FlexAlign.Center) // 子元素垂直居中对齐
  }
}

觉得有帮助,可以点赞或收藏

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐