鴻蒙Next文件下載RCP單線程和多線程使用對比

本文介紹:
1.基于RCP中提供封裝好的Session.downloadToFile()方法進行文件下載
2.基于TaskPool和RCP的三方庫SFFT實現(xiàn)多線程下載,原理是將文件分割為多個小塊,由多個線程同時下載這些部分,并發(fā)寫入到本地文件中,從而實現(xiàn)高效、穩(wěn)定的下載


多線程下載文件.png

看一下實現(xiàn)效果:

6線程演示.gif

當前網(wǎng)絡(luò)情況下,同時下同一個文件,使用SFFT多線程下載大概快10s
看一下兩種方式單獨下載的對比:發(fā)現(xiàn)相差不大。
單獨下載對比.png

看一下兩種方式同時下載,不同線程數(shù)下載對比:
3.png

4.png
8.png

簡單對比,STTF多線程下載還是相對要快一些。
接下來介紹一下兩種方式的實現(xiàn)方式:

RCP

1.創(chuàng)建HTTP會話rcp.createSession()
2.downloadToFile(url: URLOrString, downloadTo: DownloadToFile):
url:請求資源的URL
downloadTo:保存到本地文件系統(tǒng)中的指定位置

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: { //自動重定向和超時設(shè)置
        timeout: {   //接和傳輸數(shù)據(jù)所允許的最長時間
          connectMs: 1000 * 60 * 20,   //允許建立連接的最長時間
          transferMs: 1000 * 60 * 20  //允許傳輸數(shù)據(jù)的最長時間
        }
      }
    }
  };
  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,或?qū)⒃创a下載下來,作為一個module引入
在entry中oh-package.json5中增加配置"@hadss/super_fast_file_trans": "file:../library_ssf"
2.配置DownloadConfig
3.根據(jù)配置創(chuàng)建下載任務(wù) 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, // 啟用的線程數(shù),concurrency為1~8的正整數(shù)
    isBreakpointResume: false, // 是否啟用斷點續(xù)下,isBreakpointResume為true時啟用
    maxRetries: 3, // 重試次數(shù)為3次
    retryInterval: 2000, // 重試間隔為2000ms
  }
}

export async  function sfftDownload(downloadUrl:string,downloadListener: DownloadListener,concurrency?:number)  {
  await DownloadManager.getInstance().init(context as common.UIAbilityContext);
  // 根據(jù)配置創(chuàng)建下載任務(wù)
  downloadInstance = DownloadManager.getInstance().createDownloadTask(getDownloadConfig(downloadUrl,downloadUrl.split('/').pop() || '',concurrency), downloadListener);
  await downloadInstance?.start()
}

Page中下載回調(diào)配置

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;
      }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容