HarmonyOS 鸿蒙Next 使用DOWNLOAD模式保存文件出现Error: Operation not permitted
HarmonyOS 鸿蒙Next 使用DOWNLOAD模式保存文件出现Error: Operation not permitted
我需要保存一个base64格式的文件到DOWNLOAD下面,出现异常:Error: Operation not permitted 我需要保存一个base64格式的文件到DOWNLOAD下面,出现异常:Error: Operation not permitted,请问是什么原因
代码片段如下:
param = { <span class="hljs-string">"dataBase64"</span>: <span class="hljs-string">"data:audio/midi;base64,TVRoZAAAAAYAAQACAeBNVHJrAAAAIQD/UQMLcbAA/1kCAAAA/1gEBAIYCAD/AQR0dHR0AP8vAE1UcmsAAACrAMAAALB5AACwQAAAsFswALAKQACwB2QAkEdpgXCARwAAkEdVgXCARwAAkEdfgXCARwAAkEdVgXCARwAAkEBfgXCAQAAAkEVVgXCARQAAkD5fgXCAPgAAkENVgXCAQwAAkEdfgXCARwAAkEdVgXCARwAAkEdfgXCARwAAkEdVgXCARwAAkEBfgXCAQAAAkENVgXCAQwAAkEBfgXCQRVUDgEAAgXCARQAA/y8A"</span>, <span class="hljs-string">"fileType"</span>: <span class="hljs-string">"midi"</span>, <span class="hljs-string">"fileName"</span>: <span class="hljs-string">"tttt"</span> }
;
if (StringUtils.isStrNotBlank(param)) {
const h5CallBackBean: H5CallBackBean | null = JSONUtil.jsonToBean<H5CallBackBean>(H5CallBackBean, param);
<span class="hljs-keyword">if</span> (h5CallBackBean) {
<span class="hljs-keyword">if</span> (<span class="hljs-string">'midi'</span> === h5CallBackBean.fileType) {
<span class="hljs-keyword">const</span> fileBase64 = h5CallBackBean.dataBase64;
<span class="hljs-keyword">if</span> (StringUtils.isStrNotBlank(fileBase64)) {
<span class="hljs-keyword">const</span> base64: string = fileBase64.split(<span class="hljs-string">","</span>)[<span class="hljs-number">1</span>];
<span class="hljs-keyword">const</span> numTemp: number = DateUtil.getTodayTime();
<span class="hljs-keyword">let</span> uri: string = <span class="hljs-string">''</span>; <span class="hljs-comment">// 请确保 getContext(this) 返回结果为 UIAbilityContext</span>
<span class="hljs-keyword">let</span> context = getContext(<span class="hljs-keyword">this</span>) as common.Context;
<span class="hljs-keyword">const</span> documentViewPicker = <span class="hljs-keyword">new</span> picker.DocumentViewPicker(context);
<span class="hljs-keyword">const</span> documentSaveOptions = <span class="hljs-keyword">new</span> picker.DocumentSaveOptions();
documentSaveOptions.pickerMode = picker.DocumentPickerMode.DOWNLOAD;
<span class="hljs-comment">// documentSaveOptions.newFileNames = [numTemp + '.midi'];</span>
documentViewPicker.save(documentSaveOptions).then((documentSaveResult: <span class="hljs-built_in">Array</span><string>) => {
uri = documentSaveResult[<span class="hljs-number">0</span>];
console.info(<span class="hljs-string">'documentViewPicker.save succeed and uri is: '</span> + uri);
<span class="hljs-keyword">if</span> (StringUtils.isStrNotBlank(uri)) {
<span class="hljs-keyword">if</span> (UiUtils.saveBase64File(base64, uri + `/${numTemp}.midi`)) {
ToastUtil.showToast(<span class="hljs-string">"保存成功"</span>);
}
}
}).catch((err: BusinessError) => {
console.error(`Invoke documentViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
});
}
}
}
}
saveBase64File函数如下:
public static saveBase64File(base64: string, filePath: string): boolean {
if (!base64 || !filePath) {
return false;
}
<span class="hljs-keyword">const</span> imageBuffer = Base64Util.decodeSync(base64);
<span class="hljs-keyword">let</span> file: fs.File | <span class="hljs-literal">undefined</span>;
<span class="hljs-keyword">try</span> {
file = fs.openSync(filePath, fs.OpenMode.READ_WRITE);
<span class="hljs-keyword">if</span> (file !== <span class="hljs-literal">undefined</span>) {
fs.writeSync(file.fd, imageBuffer);
fs.closeSync(file);
}
} <span class="hljs-keyword">catch</span> (err) {
Logger.error(CommonConstants.TAG, `saveBase64File err: ${err}`);
<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
}
<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
}
JSONUtil.jsonToBean和 Base64Util.decodeSync(base64)使用到的是@pura/harmony-utils 1.0.2的方法
这边需要您修改几个地方,给您备注了,您看一下以下简写的代码:
```
documentViewPicker.save(documentSaveOptions).then((documentSaveResult: Array<string>) => {
uri = documentSaveResult[0];
console.info(‘documentViewPicker.save succeed and uri is:’ + uri);
//得到uri后,需要使用FileUri做一层转换,才可以做后续读写的操作
let path: string = new fileUri.FileUri(uri).path
//得到path后拼接文件名
let filePath: string = ${path}/${numTemp}.midi
;
console.info(‘documentViewPicker.save filePath:’ + filePath);
//以下是您saveBase64File方法中的代码:
const imageBuffer = Base64Util.decodeSync(base64);
try {
//这边要多加一个fs.OpenMode.CREATE得到创建文件的权限
let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
console.info("file fd: " + file.fd);
//因为writeSync的入参类型是ArrayBuffer或string,所以这边要使用.buffer转换成ArrayBuffer类型,否则会报错。
let writeLen = fs.writeSync(file.fd, imageBuffer.buffer);
console.info("file writeLen: " + writeLen);
fs.closeSync(file);
ToastUtil.showToast(“保存成功”)
} catch (err) {
console.error(saveBase64File err: ${err}
);
}
}).catch((err: BusinessError) => {
console.error(Invoke documentViewPicker.save failed, code is ${err.code}, message is ${err.message}
);
})
针对HarmonyOS 鸿蒙Next使用DOWNLOAD模式保存文件出现“Error: Operation not permitted”的问题,这通常是由于权限不足或API使用不当导致的。以下是一些可能的解决方案:
-
检查权限:
- 确保应用已正确声明并请求了
ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY
权限。 - 如果权限申请未通过或未弹框,请检查设备是否支持该权限等级,并在
module.json5
中正确配置。
- 确保应用已正确声明并请求了
-
API使用:
- 在使用
DocumentViewPicker
的save
方法时,确保提供的DocumentSaveOptions
配置正确,包括文件名、后缀等。 - 保存文件后,使用正确的URI进行后续读写操作,必要时需进行URI转换。
- 在使用
-
设备兼容性:
- 不同HarmonyOS版本和设备可能对API的支持存在差异,请确认您的设备版本是否支持所使用的API。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html。