Objective: Encapsulate the sandbox tool to save files to the sandbox and clear sandbox files.

Knowledge points:
Before using this function module to operate on files/directories, it is necessary to first obtain the application sandbox path, retrieval method, and interface:getContext().cacheDir

fs: Before using this function module to operate on files/directories, it is necessary to first obtain their application sandbox path. The string representing the sandbox path is called 'path'. Please refer to 'Application Context - Get Application File Path' for the retrieval method and interface usage.
The string pointing to a resource is called a URI. For interfaces that only support path as an input parameter, the URI can be converted to path by constructing a fileUri object and obtaining its path property, and then using the file interface.

fs.open: Open the file and use Promise asynchronous callback.
[code]
open(path: string, mode?: number): Promise
[/code]
path: The application sandbox path or file URI of the file.
mode: The option to open a file must specify one of the following options, which will be opened in read-only mode by default:

  • OpenMode. READ_ONLY(0o0): Read only open.
  • OpenMode. WRITE_ONLY(0o1): Only write open.
  • OpenMode. READ_WRITE(0o2): Read and write open. Given the following functional options, append them in a bitwise or manner, and no additional options are given by default:
  • OpenMode. CREATE(0o100): If the file does not exist, create the file.
  • OpenMode. TRUNC(0o1000): If the file exists and has write permission, crop its length to zero.
  • OpenMode. APPEND(0o2000): Open in append mode, and subsequent writes will be appended to the end of the file.
  • OpenMode. NONBLOCK(0o4000): If the path points to a FIFO, block special file, or character special file, then this open and subsequent IO operations will be non blocking.
  • OpenMode. DIR(0o200000): If the path does not point to a directory, an error occurs. Do not allow additional write permissions.
  • OpenMode. NOFOLLOW(0o400000): If the path points to a symbolic link, an error occurs.
  • OpenMode. SYNC(0o4010000): Open files in synchronous IO mode.

fs.access: Check if the current process can access a file and use Promise asynchronous callback.
fs.mkdirSync: Create a directory using synchronous methods.
fs.copyFile: Copy the file and use Promise asynchronous callback.
fs.close: Close the file and use Promise asynchronous callback.
fs.rmdir: Delete the entire directory and use Promise to return asynchronously.
fs.listFileSync: List all file names in the folder synchronously. Support recursive listing of all file names (including subdirectories) and file filtering.

Actual combat: SandboxUtil

import fs from '@ohos.file.fs';
import { util } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';

/**
 * 沙箱工具类
 */
class SandboxUtil {
  private sandboxDir:string ='/sandbox'

  /**
   * 保存文件到沙箱
   * @param src
   * @returns 沙箱地址
   */
  async saveToSandbox(src: string): Promise {
    let sandboxUri: string = ''
    for (let index = 0; index < src.length; index++) {
      const uri = src;
      try {
        const originalFile = await fs.open(uri)
        const targetFileDirPath = getContext().cacheDir + this.sandboxDir
        const fileName = util.generateRandomUUID() + uri.split("/").pop() ?? ''
        if (!fs.accessSync(targetFileDirPath)) {
          fs.mkdirSync(targetFileDirPath, true)
        }
        const targetFile =
          await fs.open(`${targetFileDirPath}/${fileName}`,
            fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
        await fs.copyFile(originalFile.fd, targetFile.fd)
        await fs.close(originalFile.fd);
        await fs.close(targetFile.fd);
        sandboxUri=targetFile.path
      } catch (e) {
        const err = e as BusinessError
        console.error(`[log]MediaPicker saveToSandbox, err=${JSON.stringify(err)}`); //err.code == 13900001 文件失效
      }
    }
    return sandboxUri
  }

  /**
   * 清除沙箱文件
   */
  clear() {
    const targetFileDirPath = getContext().cacheDir + this.sandboxDir
    fs.rmdir(targetFileDirPath);
  }

  /**
   * 获取沙箱路径下所有文件名,支持递归列出所有文件名(包含子目录下),并以日志形式打印
   * 用于检查沙箱情况
   */
  print() {
    const targetFileDir = getContext().cacheDir + this.sandboxDir
    if (fs.accessSync(targetFileDir)) {
      let listFile = fs.listFileSync(targetFileDir, { recursion: true })
      let listFileStr = listFile.join('\n');
      console.log(`[log]postVideoSandbox print, listFileStr=${JSON.stringify(listFileStr)}`);
    } else {
      console.log(`[log]postVideoSandbox print, 目标文件不存在, targetFileDir=${JSON.stringify(targetFileDir)}`);
    }
  }
}

const sandboxUtil = new SandboxUtil()

export default sandboxUtil

use

import sandboxUtil from './SandboxUtil';

@Entry
@Component
struct SandboxDemoPage {
  @State message: string = 'SandboxDemo';

  build() {
    Column() {
      Text(this.message)
        .fontSize($r('app.float.page_text_font_size'))
        .fontWeight(FontWeight.Bold)
      Button('保存文件')
        .onClick(()=>{
          sandboxUtil.saveToSandbox('fielPath')
        })
      Button('删除文件')
        .onClick(()=>{
          sandboxUtil.clear()
        })
    }
    .height('100%')
    .width('100%')
  }
}