HarmonyOS鸿蒙Next中如何复制用户文件到应用的沙箱目录?

HarmonyOS鸿蒙Next中如何复制用户文件到应用的沙箱目录? cke_171.png

cke_404.png

如题,我现在根据官方文档的指引获取到了用户的音频文件Uri,但是如何复制到应用的沙箱目录呢?


更多关于HarmonyOS鸿蒙Next中如何复制用户文件到应用的沙箱目录?的实战教程也可以访问 https://www.itying.com/category-93-b0.html

8 回复

大家好,这个问题我参考官方文档已经解决了,代码分享到下面了。 

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

/**
 *@param songUri: string[文件管理器选择音频,获取到的uri]
 * @param pathDir: string[沙箱路径 + 文件名]
 */
export function fsCopy(songUri: string, pathDir: string) {
  // 将沙箱文件路径+文件名  转换为uri
  let dstDirUriLocal: string = fileUri.getUriFromPath(pathDir);
  console.log('songUri: ' + songUri)
  console.log('dstDirUriLocal: ' + dstDirUriLocal)
  let progressListener: fs.ProgressListener = (progress: fs.Progress) => {
    console.info(`progressSize: ${progress.processedSize}, totalSize: ${progress.totalSize}`);
  };
  let copyOption: fs.CopyOptions = {
    "progressListener": progressListener
  }
  try {
    fs.copy(songUri, dstDirUriLocal, copyOption).then(() => {
      console.info("Succeeded in copying.");
    }).catch((err: BusinessError) => {
      console.error(`Failed to copy. Code: ${err.code}, message: ${err.message}`);
    })
  } catch (err) {
    console.error(`Failed to copy.Code: ${err.code}, message: ${err.message}`);
  }
}

更多关于HarmonyOS鸿蒙Next中如何复制用户文件到应用的沙箱目录?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


1/使用PhotoViewPicker或DocumentViewPicker选择文件,获取用户文件的URI

2/通过fileUri.getUriFromPath将URI转换为可访问的路径

3/执行文件复制操作

import picker from '@kit.CoreFileKit';

import fs from '@kit.CoreFileKit';

import common from '@kit.AbilityKit';

async function copyToSandbox(context: common.Context, userUri: string) {

  try {

    // 打开用户文件

    const srcFile = fs.openSync(userUri, fs.OpenMode.READ_ONLY);

    

    // 创建沙箱目标文件

    const sandboxPath = `${context.filesDir}/audio_file.mp3`;

    const destFile = fs.openSync(sandboxPath, 

      fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);

    

    // 执行复制操作

    await fs.copyFile(srcFile.fd, destFile.fd);

    

    // 关闭文件描述符

    fs.closeSync(srcFile);

    fs.closeSync(destFile);

    

    console.info('文件复制成功');

  } catch (err) {

    console.error(`复制失败: ${err.code}, ${err.message}`);

  }

}

用fs.copy直接复制到沙箱即可,注意沙箱路径需要用getUIContext.getHostContext()获取

import common from '@ohos.app.ability.common';
await fs.copy(uris,this.getUIContext.getHostContext())
let documentPicker = new picker.DocumentViewPicker(context);
let selectResult: string[] =
  await documentPicker.select({ fileSuffixFilters: ['.mp3', '.flac', '.ogg', '.wav'], maxSelectNumber: 500 });

这个是我用来获取用户文件的方法

  1. 用户需要分享文件、保存图片、视频等用户文件时,开发者可以通过系统预置的文件选择器(FilePicker),实现该能力。通过Picker访问相关文件,将拉起对应的应用,引导用户完成界面操作,接口本身无需申请权限。Picker获取的URI只具有临时权限,获取持久化权限需要通过FilePicker设置永久授权方式获取。

根据用户文件的常见类型,选择器(FilePicker)分别提供以下选项:

  • PhotoViewPicker:适用于图片或视频类型文件的选择与保存(该接口在后续版本不再演进)。请使用PhotoAccessHelper的PhotoViewPicker来选择图片文件。请使用安全控件保存媒体库资源

  • DocumentViewPicker:适用于文件类型文件的选择与保存。DocumentViewPicker对接的选择资源来自于FilePicker,负责文件类型的资源管理,文件类型不区分后缀,比如浏览器下载的图片、文档等,都属于文件类型。

  • AudioViewPicker:适用于音频类型文件的选择与保存。AudioViewPicker目前对接的选择资源来自于AudioPicker。

在HarmonyOS Next中,使用@ohos.file.fs@ohos.file.userFileManager模块实现文件复制。通过userFileManager.getPhotoAccessHelper()获取用户文件访问权限,使用fs.copyFile()fs.copyDir()将指定文件复制到应用沙箱路径(如context.filesDir)。需在module.json5中声明ohos.permission.READ_IMAGEVIDEOohos.permission.WRITE_IMAGEVIDEO权限。

在HarmonyOS Next中,通过PhotoAccessHelper获取用户文件Uri后,可以使用FileManager API将文件复制到应用沙箱目录。以下是关键步骤:

  1. 获取文件输入流:通过Uri打开文件输入流。
  2. 创建沙箱输出文件:使用应用上下文获取沙箱目录路径,并创建目标文件。
  3. 复制数据:通过流读写操作完成复制。

示例代码:

import fs from '@ohos.file.fs';
import photoAccessHelper from '@ohos.file.photoAccessHelper';

async function copyToSandbox(uri: string, fileName: string): Promise<void> {
  try {
    // 打开源文件
    let srcFile = await fs.open(uri, fs.OpenMode.READ_ONLY);
    
    // 获取沙箱目录路径
    let sandboxDir = globalThis.context.filesDir;
    let destPath = sandboxDir + '/' + fileName;
    
    // 创建目标文件
    let destFile = await fs.open(destPath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
    
    // 复制数据
    await fs.copyFile(srcFile.fd, destFile.fd);
    
    // 关闭文件
    await fs.close(srcFile.fd);
    await fs.close(destFile.fd);
  } catch (error) {
    console.error('Copy failed: ' + error.message);
  }
}

注意事项:

  • 需申请ohos.permission.READ_IMAGEVIDEO权限
  • 目标文件名需唯一避免冲突
  • 大文件建议使用分块读写避免内存问题
回到顶部