鸿蒙Next文件下载RCP单线程和多线程使用对比 原创

auhgnixgnahz
发布于 2025-6-12 21:21
浏览
0收藏

本文介绍:
1.基于RCP中提供封装好的Session.downloadToFile()方法进行文件下载
2.基于TaskPool和RCP的三方库SFFT实现多线程下载,原理是将文件分割为多个小块,由多个线程同时下载这些部分,并发写入到本地文件中,从而实现高效、稳定的下载
鸿蒙Next文件下载RCP单线程和多线程使用对比-鸿蒙开发者社区

看一下实现效果:
鸿蒙Next文件下载RCP单线程和多线程使用对比-鸿蒙开发者社区
当前网络情况下,同时下同一个文件,使用SFFT多线程下载大概快10s
看一下两种方式单独下载的对比:发现相差不大。
鸿蒙Next文件下载RCP单线程和多线程使用对比-鸿蒙开发者社区
看一下两种方式同时下载,不同线程数下载对比:
鸿蒙Next文件下载RCP单线程和多线程使用对比-鸿蒙开发者社区

鸿蒙Next文件下载RCP单线程和多线程使用对比-鸿蒙开发者社区

鸿蒙Next文件下载RCP单线程和多线程使用对比-鸿蒙开发者社区
简单对比,STTF多线程下载还是相对要快一些。
接下来介绍一下两种方式的实现方式:

RCP

1.创建HTTP会话rcp.createSession()
2.downloadToFile(url: URLOrString, downloadTo: DownloadToFile):
url:请求资源的URL
downloadTo:保存到本地文件系统中的指定位置

const uiContext: UIContext | undefined = AppStorage.get('uiContext');
let context = uiContext!.getHostContext()!;

function genSessionConfig(httpEventsHandler?: rcp.HttpEventsHandler) {
  const config: rcp.SessionConfiguration = {
    baseAddress: ApiConstants.SERVER,
    requestConfiguration: {
      tracing: { httpEventsHandler },
      transfer: { //自动重定向和超时设置
        timeout: {   //接和传输数据所允许的最长时间
          connectMs: 1000 * 60 * 20,   //允许建立连接的最长时间
          transferMs: 1000 * 60 * 20  //允许传输数据的最长时间
        }
      }
    }
  };
  return config;
}
export function download(downloadUrl: string, httpEventsHandler: rcp.HttpEventsHandler) {
  const destPath =`${context.filesDir}/${downloadUrl.split('/').pop() || ''}`;
  const rcpSession = rcp.createSession(genSessionConfig(httpEventsHandler));
  const downloadTo: rcp.DownloadToFile = {
    kind: 'file',
    file: destPath
  };
  return rcpSession.downloadToFile(downloadUrl, downloadTo)
    .then(() => destPath)
    .finally(() => {
      rcpSession.close();
    });
}

SFFT

1.引入第三方库,gitcode搜索super_fast_file_trans,或将源码下载下来,作为一个module引入
在entry中oh-package.json5中增加配置"@hadss/super_fast_file_trans": “file:…/library_ssf”
2.配置DownloadConfig
3.根据配置创建下载任务 DownloadManager.getInstance().createDownloadTask
4.start()开始下载

const uiContext: UIContext | undefined = AppStorage.get('uiContext');
let context = uiContext!.getHostContext()!;
let downloadInstance: DownloadTask | undefined;
function  getDownloadConfig(url:string,fileName:string,concurrency?:number): DownloadConfig{
  return {
    url: url, // 远端文件url地址
    fileName: fileName+'ssf', // 本地文件名
    concurrency:concurrency!=0?concurrency:1, // 启用的线程数,concurrency为1~8的正整数
    isBreakpointResume: false, // 是否启用断点续下,isBreakpointResume为true时启用
    maxRetries: 3, // 重试次数为3次
    retryInterval: 2000, // 重试间隔为2000ms
  }
}

export async  function sfftDownload(downloadUrl:string,downloadListener: DownloadListener,concurrency?:number)  {
  await DownloadManager.getInstance().init(context as common.UIAbilityContext);
  // 根据配置创建下载任务
  downloadInstance = DownloadManager.getInstance().createDownloadTask(getDownloadConfig(downloadUrl,downloadUrl.split('/').pop() || '',concurrency), downloadListener);
  await downloadInstance?.start()
}

Page中下载回调配置

this.downloadListener = {
      onStart: (trialResponseHeaders: Record<string, string | string[] | undefined>) => {
        this.ssfstarttime = new Date().getTime()
      },
      onSuccess: (filePath: string) => {
        this.ssfdownloadtime = (new Date().getTime() - this.ssfstarttime) / 1000
        this.ssfProgress = 0;
      },
      onProgressUpdate: (downloadProgress: DownloadProgressInfo) => {
        let transferredSize = downloadProgress.transferredSize;
        this.totalSize = downloadProgress.totalSize;
        this.speed = downloadProgress.speed/1024/1024;
        this.ssfProgress = transferredSize / this.totalSize * 100;
      }
    }

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
收藏
回复
举报
回复
    相关推荐