HarmonyOS鸿蒙Next中web组件下载文件时如何让用户选择指定目录并保存文件?

HarmonyOS鸿蒙Next中web组件下载文件时如何让用户选择指定目录并保存文件?

用了下面这个博客的方案,可以保存到下载目录下

https://developer.huawei.com/consumer/cn/forum/topic/0204165483221878979?fid=0109140870620153026

但是,在鸿蒙PC端,我想弹窗,让用户选择保存目录

private async getDownloadPathFromPicker(fileName: string): Promise<string> {
  const documentPicker = new picker.DocumentViewPicker();
  return new Promise<string>(resolve => {
    try {
      const documentSaveOptions = new picker.DocumentSaveOptions();
      documentSaveOptions.newFileNames = [fileName];
      documentSaveOptions.pickerMode = picker.DocumentPickerMode.DEFAULT;
      documentPicker.save(documentSaveOptions).then(async (documentSaveResult: Array<string>) => {
        if (documentSaveResult.length <= 0) {
          resolve('');
          return;
        }
        const uriString = documentSaveResult[0];
        if (!uriString) {
          resolve('');
          return;
        }
        const uri = new fileUri.FileUri(uriString);
        resolve(uri.path);
      }).catch((err: BusinessError) => {
        console.error(`ErrorCode: ${err.code},  Message: ${err.message}`);
        resolve('');
      });
    } catch (error) {
      resolve('');
    }
  })
}

使用了上面代码后,发现桌面上是新增了一个同名文件,但是大小是0kb

并且触发了onDownloadFailed,返回-2,请问该如何修复


更多关于HarmonyOS鸿蒙Next中web组件下载文件时如何让用户选择指定目录并保存文件?的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

可以试试以下方法:

1. 设置下载委托:

在你的Web控制器中,首先需要设置一个下载委托,这个委托将负责处理下载过程中的各种事件,包括下载前的确认、下载进度更新、下载失败和下载完成。

let controller: webview.WebviewController = new webview.WebviewController();
let delegate: webview.WebDownloadDelegate = new webview.WebDownloadDelegate();

controller.setDownloadDelegate(delegate);

2. 处理下载前事件:

在下载文件之前,可以通过onBeforeDownload方法来获取下载项,并设置下载路径。这里,你可以弹出一个文件选择器,让用户选择保存目录。

delegate.onBeforeDownload((webDownloadItem: webview.WebDownloadItem) => {
    console.log("将开始下载。");
    // 弹出文件选择器,让用户选择保存路径
    let savePath = "/data/storage/el2/base/cache/web/" + webDownloadItem.getSuggestedFileName();
    webDownloadItem.start(savePath);
});

3. 处理下载进度更新:

可以通过onDownloadUpdated方法来更新下载进度,显示当前的下载速度和进度百分比。

delegate.onDownloadUpdated((webDownloadItem: webview.WebDownloadItem) => {
    console.log("下载更新标识:" + webDownloadItem.getGuid());
    console.log("下载进度:" + webDownloadItem.getPercentComplete());
    console.log("当前下载速度:" + webDownloadItem.getCurrentSpeed());
});

4. 处理下载完成和失败:

分别通过onDownloadFinishonDownloadFailed方法来处理下载完成和失败的情况。

delegate.onDownloadFinish((webDownloadItem: webview.WebDownloadItem) => {
    console.log("下载完成标识:" + webDownloadItem.getGuid());
});

delegate.onDownloadFailed((webDownloadItem: webview.WebDownloadItem) => {
    console.error("下载失败标识:" + webDownloadItem.getGuid());
    console.error("下载失败错误码:" + webDownloadItem.getLastErrorCode());
});

更多关于HarmonyOS鸿蒙Next中web组件下载文件时如何让用户选择指定目录并保存文件?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


运行正常,能正常写入

在HarmonyOS鸿蒙Next中,使用Web组件下载文件时,可通过FilePicker模块让用户选择目录。调用filePicker.select方法,设置typefiledirectory,用户选择后获取URI。通过ohos.file.fs模块的fs.copyfs.move将临时文件保存至目标路径。需配置dataStoragefileIO权限。示例代码片段:

let filePicker = new FilePicker();
filePicker.select(...);

路径操作使用fsAPI完成。

在HarmonyOS Next中实现Web组件下载文件并让用户选择保存目录时,文件大小为0KB的问题通常是由于文件写入流程未正确处理导致的。以下是解决方案:

  1. 确保在获取用户选择的目录后,正确将下载的文件内容写入目标路径。您需要将下载的文件流写入到通过DocumentViewPicker获取的路径中。

  2. 修改后的核心代码逻辑应该是:

// 获取下载内容
const response = await fetch(downloadUrl);
const blob = await response.blob();

// 获取用户选择的保存路径
const savePath = await getDownloadPathFromPicker(fileName);
if (!savePath) return;

// 将blob写入文件
const fs = await fileio.open(savePath, fileio.OpenMode.CREATE | fileio.OpenMode.READ_WRITE);
await fileio.write(fs, await blob.arrayBuffer());
await fileio.close(fs);
  1. 常见错误-2通常表示文件写入失败,请检查:
  • 是否获得了正确的写入权限
  • 目标路径是否可写
  • 是否正确处理了文件流转换
  1. 对于Web组件下载,建议监听onDownloadStart事件,取消默认下载行为,然后使用上述方法实现自定义下载流程。

注意:确保在config.json中声明了必要的文件访问权限。

回到顶部