HarmonyOS 鸿蒙Next 使用DOWNLOAD模式保存文件出现Error: Operation not permitted

发布于 1周前 作者 eggper 最后一次编辑是 5天前 来自 鸿蒙OS

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>&lt;string&gt;) =&gt; {
                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) =&gt; {
                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的方法

4 回复
您这些H5CallBackBean、JSONUtil、StringUtils是自己封装的吗?这边主要是想复现一下您的问题,目前通过代码片段不太好运行哈。最好是提供一下详细代码,另外您报错是在saveBase64File方法里报错的吗?最好提供一下报错截图,方便帮您定位。

这边需要您修改几个地方,给您备注了,您看一下以下简写的代码:

```

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});

            })

试一下去掉data:audio/midi;base64前缀呢
需要写一段授权代码,获取文件写入权限。

针对HarmonyOS 鸿蒙Next使用DOWNLOAD模式保存文件出现“Error: Operation not permitted”的问题,这通常是由于权限不足或API使用不当导致的。以下是一些可能的解决方案:

  1. 检查权限

    • 确保应用已正确声明并请求了ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY权限。
    • 如果权限申请未通过或未弹框,请检查设备是否支持该权限等级,并在module.json5中正确配置。
  2. API使用

    • 在使用DocumentViewPickersave方法时,确保提供的DocumentSaveOptions配置正确,包括文件名、后缀等。
    • 保存文件后,使用正确的URI进行后续读写操作,必要时需进行URI转换。
  3. 设备兼容性

    • 不同HarmonyOS版本和设备可能对API的支持存在差异,请确认您的设备版本是否支持所使用的API。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部