写点什么

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

作者:auhgnixgnahz
  • 2025-06-25
    北京
  • 本文字数:1864 字

    阅读完需:约 6 分钟

本文介绍:


1.基于 RCP 中提供封装好的 Session.downloadToFile()方法进行文件下载


2.基于 TaskPool 和 RCP 的三方库 SFFT 实现多线程下载,原理是将文件分割为多个小块,由多个线程同时下载这些部分,并发写入到本地文件中,从而实现高效、稳定的下载



看一下实现效果:



当前网络情况下,同时下同一个文件,使用 SFFT 多线程下载大概快 10s


看一下两种方式单独下载的对比:发现相差不大。



看一下两种方式同时下载,不同线程数下载对比:





简单对比,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;      }    }</string, string | string[] | undefined>
复制代码


发布于: 刚刚阅读数: 2
用户头像

auhgnixgnahz

关注

还未添加个人签名 2018-07-10 加入

欢迎关注:HarmonyOS开发笔记

评论

发布
暂无评论
鸿蒙Next文件下载RCP单线程和多线程使用对比_鸿蒙Next_auhgnixgnahz_InfoQ写作社区