HarmonyOS 鸿蒙Next request.downloadFile 在多文件下载的时候,如何依次下载

HarmonyOS 鸿蒙Next request.downloadFile 在多文件下载的时候,如何依次下载 目前有一个下载场景,下载的文件比较多,为了能更好对下载进行管控需要实现同步下载。目前使用的方案是将requer.downloadFile()写成一个function

export  function httpGetFile(fileUrl:string,sotrePath:string):Promise<boolean>{ }

然后在下载的时候,是这样调用的:

files.forEach ( (file,index)=>{
  let url=`${file.url}&access_session=${session}`
  let fileFullPath = `${storeDir}/${file.filename}`
  getFile(url,fileFullPath)
})

测试的时候,getFile()是异步调用的,各文件同时进行下载,而不是进行依次下载

然后进行了修改,增加了await 代码如下:

files.forEach ( async (file,index)=>{
  let url=`${file.url}&access_session=${tokensession`
  let fileFullPath = `${storeDir}/${file.filename}`
  await getFile(url,fileFullPath)
})

再次进行的时候,各文件还是同时进行下载,不是想要的依次下载。

有知道的朋友帮忙指点下,先行谢过。


更多关于HarmonyOS 鸿蒙Next request.downloadFile 在多文件下载的时候,如何依次下载的实战教程也可以访问 https://www.itying.com/category-93-b0.html

16 回复

原因可能在于httpRequest.request的回调里,虽然你的httpRequest.request是同步的,但是实际的保存文件动作在httpRequest.request的回调里进行,应该在这里加上一些处理。

比如,设置一个全局的变量isSaving,默认是false,在发起httpRequest.request请求前判断是否为false,只有为false时才发起下载请求。在发起请求时把isSaving设置为true,这样就不会发起新的httpRequest.request下载请求了。在httpRequest.request的回调里判断是否保存文件完毕,保存完毕了再设置isSaving为false,这样就允许发起新的下载请求。

更多关于HarmonyOS 鸿蒙Next request.downloadFile 在多文件下载的时候,如何依次下载的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


感谢您的指点,给我打开的思路。非常感谢。我用您的思路和方法再试。

搞定了。基本的方法就是在封装request.downloadFile为functions,在其downloadTaskoncomplete的callback进行递归调用。测试通过。稍晚一点儿,整理一下发出来。

大佬,有demo可以发一下吗

补充一句,使用requestDownloadFile()系统会自动发一个Notification,包括进度、以及一个可以“取消”下载的操作按钮。notification的titile可以在requestDownloadFile()中进行设置。

找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:BV1S4411E7LY/?p=17

解决的代码真的很简单, 就是利用其on,Complete回调函数,在一次下载完成后进行下一次下载,这样便可按照设计要求依次下载。

涉及到的接口是request.downloadFile()

function downloadFile(context: BaseContext, config: DownloadConfig, callback: AsyncCallback<DownloadTask>): void;

异步回调的类DownloadTask:

on(type: 'complete' | 'pause' | 'remove', callback: () => void): void;

下载函数

/**
 * 通过HTTP协议获取文件并下载。
 * @param storeDir 存储目录,文件将下载到此目录。
 * @param index 当前处理的链接索引,用于遍历links数组。
 * @param links 包含多个下载链接的数组。
 * @param event 用于同步事件通知的对象。
 */
export function HttpGetFiles(storeDir: string, token: string, index: number, links: DownloadLink[], event: DownloadEvent) {
  let downloadTask: request.DownloadTask
  let item = links[index]
  let url = ${item.dlink}
  let fullPath = `${storeDir}/${item.filename}` // 计算文件的完整路径
  event.curFilename = item.filename // 当前处理的文件名
  event.currentIndex = index // 当前处理的索引

  // 检查文件是否已存在,如果存在则删除
  if (fs.accessSync(fullPath)) {
    logger.info('file exist,delete it')
    fs.unlinkSync(fullPath)
  }

  try {
    // 发起文件下载请求
    request.downloadFile(FileUtils.getAppContext(), { url: url, filePath: fullPath, background: true, title: item.filename }, (err, data) => {
      if (err) {
        logger.error('Failed to request the download. Cause: ' + JSON.stringify(err));
        Helper.sendEvent(SyncStatus.SYNC_FAILED, event)
      }
      downloadTask = data

      // 下载完成的回调函数
      let completeCallback = () => {
        logger.info(`file:${event.curFilename} download succeed`)
        event.singleProgress = 1
        Helper.sendcEvent(SyncStatus.SYNC_FINISHED, event)
        if (index + 1 < links.length) {
          HttpGetFiles(storeDir, token, index + 1, links, event) // 下载下一个文件
        }
      };
      downloadTask.on('complete', completeCallback);

      // 下载暂停的回调函数
      let pauseCallback = () => {
        logger.info('Download task pause.');
        Helper.sendEvent(SyncStatus.SYNC_PAUSED, event)
      };
      downloadTask.on('pause', pauseCallback);

      // 下载任务移除的回调函数
      let removeCallback = () => {
        logger.info('Download task remove.');
        Helper.sendEvent(NetDiskStatus.REMOVED, event)
      };
      downloadTask.on('remove', removeCallback);

      // 下载进度的回调函数
      let progressCallback = (receivedSize, totalSize) => {
        event.singleProgress = receivedSize / totalSize
        Helper.sendEvent(yncStatus.SYNCING, event)
        logger.info("download receivedSize:" + receivedSize + " totalSize:" + totalSize);
      };
      downloadTask.on('progress', progressCallback);
    })
  } catch (err) {
    Helper.sendEvent(SyncStatus.SYNC_FAILED, event)
    logger.error('err.code : ' + err.code + ', err.message : ' + err.message);
  }
}

Helper.sendEvent()使用的是Appstoreage和UI同步状态。DownloadEvent是构造了一个同步事件类,由于我使用的是Api9, 无法在Object和class上使用@StoreageProp.

下载单个文件 后端返回链接的格式 但是没有下载到本地文件夹中

报错13400002 根目录我是这样取得let context = getContext(this) as common.UIAbilityContext;

兄弟,等你的整理,问一下,你下载到context.filesDir的文件可以通过系统的文件管理应用看到吗?



找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:BV1S4411E7LY/?p=17

我使用的是Dev Eco 4 Api9 ,测试我使用的是模拟器,在模拟器的文件管理应用中没有看到下载的文件。下载日志是可以看到文件是成功下载的。

这个是下载到沙箱的,要在文件管理里面看需要复制一份进去,

async使用后,不应该调用await吗?,没有看到代码调用await

对,贴子里面忘了写进去了。

files.forEach(async (file, index) => { let url = ${file.url}&access_session=${tokensession}; let fileFullPath = ${storeDir}/${file.filename}; await getFile(url, fileFullPath); }),

在HarmonyOS鸿蒙系统中,当使用request.downloadFile进行多文件下载并希望依次下载时,可以通过以下方式实现:

首先,你需要维护一个文件下载列表,该列表包含所有需要下载的文件信息(如URL、文件名等)。然后,使用一个递归或循环的机制来依次触发下载请求。

具体步骤如下:

  1. 初始化一个下载列表,包含所有待下载文件的详细信息。
  2. 创建一个下载函数,该函数接受当前下载的文件信息作为参数。
  3. 在下载函数中,使用request.downloadFile方法下载文件。
  4. 下载完成后,检查下载列表是否还有剩余文件。如果有,则递归调用下载函数并传入下一个文件的信息。
  5. 如果下载列表为空,则表示所有文件已下载完成。

示例代码(伪代码):

function downloadFiles(fileList, index = 0) {
    if (index >= fileList.length) {
        return; // 所有文件下载完成
    }
    const fileInfo = fileList[index];
    request.downloadFile({
        url: fileInfo.url,
        success: () => {
            // 下载成功,递归下载下一个文件
            downloadFiles(fileList, index + 1);
        },
        fail: () => {
            // 下载失败处理
            // 可选择重试或记录错误
        }
    });
}

请注意,上述代码为伪代码,具体实现需根据HarmonyOS鸿蒙系统的API文档进行调整。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部