HarmonyOS NEXT Practical: Sandbox Tool

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)

Mar 26, 2025 - 12:54
 0
HarmonyOS NEXT Practical: Sandbox Tool

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%')
  }
}