HarmonyOS 鸿蒙Next中如何将图库中的图片复制到自己的应用沙箱?
HarmonyOS 鸿蒙Next中如何将图库中的图片复制到自己的应用沙箱? 使用photoAccessHelper.PhotoViewPicker,拉起图库,选择一张图片,然后用fs的cpoy方法将选择的图片复制到自己的沙箱路径,发现复制不了。
3 回复
你好,将图库的图片复制到自己应用沙箱,可以用@ohos.file.fs 模块的fs.copyFile或者fs.copyFileSync 方法进行复制。示例如下:
import { fileUri } from '@kit.CoreFileKit';
import fs from '[@ohos](/user/ohos).file.fs';
import { abilityAccessCtrl, common, PermissionRequestResult, Permissions } from '@kit.AbilityKit';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
@Entry
@Component
struct Index {
private srcUri: string = '';
@State src: string = fileUri.getUriFromPath(this.srcUri);
@State copySrc: string = '';
aboutToAppear(): void {
this.requestPermissions(["ohos.permission.READ_IMAGEVIDEO", "ohos.permission.WRITE_IMAGEVIDEO"]);
}
requestPermissions(permissions: Array<Permissions>): void {
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
atManager.requestPermissionsFromUser(this.getUIContext().getHostContext() as common.UIAbilityContext, permissions)
.then((data: PermissionRequestResult) => {
})
.catch((err: Error) => {
})
}
copyFile(): void {
console.info(`=-=:srcUri will copied: ${this.srcUri}`);
try {
let sourceFile: fs.File = fs.openSync(this.srcUri, fs.OpenMode.READ_WRITE);
let context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext;
const base: string = context.filesDir;
const resourcesDir: string = `${base}/resources`;
const baseDir: string = `${resourcesDir}/base`;
const mediaDir: string = `${baseDir}/media`;
if (!fs.accessSync(mediaDir)) {
fs.mkdirSync(mediaDir, true);
}
let destDir: string = `${mediaDir}/test.jpg`; //沙箱路径:/data/storage/el2/base/haps/entry/files/resources/base/media/test.jpg
console.info(`=-=:destDir: ${destDir}`);
if (fs.accessSync(destDir)) {
console.info(`=-=:destDir: is exist`);
fs.unlinkSync(destDir);
}
let destFile: fs.File = fs.openSync(destDir, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
fs.copyFileSync(sourceFile.fd, destFile.fd);
console.info(`=-=: copyFile success:target file;${destFile.path}`);
this.copySrc = `file://${destDir}`;
console.info(`=-=: this.copySrc:${this.copySrc}`);
fs.closeSync(sourceFile);
} catch (error) {
console.error(`=-=: copyFile fail:${JSON.stringify(error)}`);
}
}
private async selectImage(): Promise<void> {
const picker: photoAccessHelper.PhotoViewPicker = new photoAccessHelper.PhotoViewPicker();
try {
const selectResult: photoAccessHelper.PhotoSelectResult = await picker.select({ maxSelectNumber: 1 });
const uris: string[] = selectResult.photoUris;
if (!uris || uris.length === 0) {
console.warn('=-=:ImageManager: No image selected');
}
console.log(`=-=:the selectImage:${JSON.stringify(uris)}`);
this.srcUri = uris[0]; //这里只获取一张图片
this.src = fileUri.getUriFromPath(this.srcUri);
console.log(`=-=:the load image path:${this.src}`);
} catch (error) {
console.error(`=-=:selectImage fail:${JSON.stringify(error)}`);
}
}
build() {
Column({ space: 20 }) {
Column() {
Text('SelectedImage:')
Image(this.src)
.height(50)
.width(50)
.onError((error: ImageError) => {
console.error('=-=:load image err' + JSON.stringify(error));
})
}
Column() {
Text('CopiedImage:')
Image(this.copySrc)
.height(50)
.width(50)
.onError((error: ImageError) => {
console.error('=-=:load CopiedImage err' + JSON.stringify(error));
})
}
Button('Select File')
.onClick((event: ClickEvent) => {
this.selectImage();
})
Button('Copy file')
.onClick((event: ClickEvent) => {
this.copyFile();
})
}
.height('100%')
.width('100%')
}
}

更多关于HarmonyOS 鸿蒙Next中如何将图库中的图片复制到自己的应用沙箱?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,使用photoAccessHelper模块获取图库图片的URI,然后通过fs模块的copyFile方法将图片复制到应用沙箱目录。需要申请ohos.permission.READ_IMAGEVIDEO权限。具体步骤:获取图片URI后,调用fs.copyFile(srcUri, destUri)完成复制。
在HarmonyOS Next中,将图库图片复制到应用沙箱的正确方式是使用photoAccessHelper模块获取图片的Uri,然后通过安全访问框架复制文件,而不是直接使用fs.copy。以下是关键步骤:
-
使用PhotoViewPicker选择图片:
import photoAccessHelper from '[@ohos](/user/ohos).file.photoAccessHelper'; let photoPicker = new photoAccessHelper.PhotoViewPicker(); photoPicker.select({ maxSelectNumber: 1, MIMEType: ['image/*'] }).then((photoSelectResult: photoAccessHelper.PhotoSelectResult) => { if (photoSelectResult.photoUris.length > 0) { let selectedUri = photoSelectResult.photoUris[0]; // 获取Uri后复制到沙箱 copyToSandbox(selectedUri); } }).catch((err: Error) => { console.error('选择图片失败:', err); }); -
通过安全访问框架复制文件:
import fs from '[@ohos](/user/ohos).file.fs'; import { BusinessError } from '[@ohos](/user/ohos).base'; async function copyToSandbox(uri: string) { let sandboxPath: string = getContext().filesDir + '/myImage.jpg'; // 沙箱目标路径 try { // 1. 通过Uri打开源文件 let srcFile = fs.openSync(uri, fs.OpenMode.READ_ONLY); // 2. 创建目标文件 let destFile = fs.openSync(sandboxPath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE); // 3. 复制数据 let bufferSize = 1024 * 1024; // 1MB缓冲区 let buffer = new ArrayBuffer(bufferSize); let offset = 0; while (true) { let readResult = fs.readSync(srcFile.fd, buffer, { offset: offset }); if (readResult.bytesRead === 0) { break; } fs.writeSync(destFile.fd, buffer, { offset: offset }); offset += readResult.bytesRead; } // 4. 关闭文件 fs.closeSync(srcFile); fs.closeSync(destFile); console.log('复制成功,路径:', sandboxPath); } catch (err) { let error = err as BusinessError; console.error('复制失败:', error.code, error.message); } }
关键注意事项:
- 确保在
module.json5中声明必要权限:{ "requestPermissions": [ { "name": "ohos.permission.READ_IMAGEVIDEO" } ] } - 直接使用fs.copy可能因权限不足失败,需通过Uri逐步读写
- 大文件建议分块读写,避免内存溢出
- 目标路径需使用应用沙箱路径(
filesDir、cacheDir等)
如果仍遇到问题,请检查:
- Uri格式是否正确(应以
file://或dataability://开头) - 是否已授予媒体文件访问权限
- 目标路径是否可写

