下载断点续传接口文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-request-V5\#offfailed10
目前遇到的问题:
1、下载断点续传在下载过程中,app终止时下载任务还在执行中,第二次打开发现下载文件已经成功了。
2、下载失败没有错误信息,无法定位错误来源。例如下载begin越界导致的失败。
代码如下:
import { Response } from '../DownloadResponse';
import { Chain, Interceptor, Task } from './Interceptor';
import { request } from '@kit.BasicServicesKit';
import { logger } from '../utils/Logger';
import { Directory, File } from '../context/FileManager';
import { exist, getFileSize } from '../utils/fileUtils';
const TAG: string = 'DownloadInterceptor';
export class DownloadInterceptor implements Interceptor {
async intercept(chain: Chain): Promise<Response> {
const fileManager = chain.request().context.fileManager;
const downloadRequest = chain.request();
const task = chain.task();
const targetPath = fileManager.getFilePath(downloadRequest.id, Directory.TMP, File.DOWNLOAD)
let size = 0
if (await exist(targetPath)) {
size = await getFileSize(targetPath)
}
const downloadConfig: request.agent.Config = {
action: request.agent.Action.DOWNLOAD,
url: downloadRequest.entity.url || '',
method: 'GET',
title: 'download',
mode: request.agent.Mode.BACKGROUND,
begins: size > 0 ? size : 0,
retry: true,
network: request.agent.Network.ANY,
saveas: targetPath,
overwrite: true,
};
logger.info(`downloadFile, downloadConfig = ${JSON.stringify(downloadConfig)}`);
try {
const downloadTask = await request.agent.create(chain.request().context.context, downloadConfig);
const downloadPromise = new Promise<Response>((resolve) => {
const cancel = () => {
this.deleteTask(downloadTask);
this.unregister(task, cancel)
resolve(Response.fail("downloadTask cancel"));
};
this.register(task, cancel)
downloadTask.on('progress', (progress: request.agent.Progress) => {
logger.info(TAG, `progress, progress = ${progress.processed} ${progress.state} ${JSON.stringify(progress)}`);
const currentSize = progress.processed + size;
const totalSize = progress.sizes[0] + size;
let progressNum: number = Math.floor(currentSize / totalSize * 100);
if (progressNum <= 100) {
chain.request().onProgress(currentSize, totalSize, progressNum, -1)
}
});
downloadTask.on('completed', (progress: request.agent.Progress) => {
logger.info(TAG, `completed, completed = ${JSON.stringify(progress)}`);
this.deleteTask(downloadTask);
this.unregister(task, cancel)
const totalSize = progress.sizes[0] + size;
chain.request().onProgress(totalSize, totalSize, 100, -1)
const response = Response.success(targetPath, Response.SOURCE_NETWORK)
response.extra['downloadSize'] = progress.sizes[0]
resolve(response);
});
downloadTask.on('failed', async (progress: request.agent.Progress) => {
logger.info(TAG, `failed, completed = ${JSON.stringify(progress)}`);
this.deleteTask(downloadTask);
this.unregister(task, cancel)
resolve(Response.fail("downloadTask fail"));
});
});
await downloadTask.start();
return downloadPromise;
} catch (err) {
logger.error(TAG, `downloadTask err, err = ${JSON.stringify(err)}`);
return Response.fail('downloadTask err', err)
}
}
register(task: Task, cancel: () => void) {
task.on('cancel', cancel);
}
unregister(task: Task, cancel: () => void) {
task.off('cancel', cancel);
}
async deleteTask(downloadTask: request.agent.Task) {
try {
downloadTask.off('progress');
downloadTask.off('completed');
downloadTask.off('failed');
await request.agent.remove(downloadTask.tid);
} catch (err) {
logger.info(TAG, `deleteTask fail, err= ${JSON.stringify(err)}`);
}
}
}
export const DefaultDownload = new DownloadInterceptor();
断点续传的文档和示例参考:
https://gitee.com/harmonyos\_samples/remote-communication-kit\_-sample-code\_-arkts/blob/master/entry/src/main/ets/pages/transferRange.ets
https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/remote-communication-rcp-V5\#section838945575618
断点续传的实现需要依赖于服务器,客户端仅支持通过设置下载的开始位置和结束位置来控制是否断点续传begins和ends当前能实现基础的分段上传下载能力,完整的断点续传功能需要自行实现具体的下载拼接逻辑。overwrite若设置为false则在第二次下载时会报错文件已存在,若设置为true则会覆写此文件。具体实现逻辑可参考设置overwrite为true,下载中断后需要一个逻辑重命名并将两次下载文件进行拼接,下载完成并拼接后覆盖之前的下载文件。