需求:从后台给的文件地址下载到本地,并让用户保存在文件夹中。
后来测试进行二次修改,现在下载文件都没有问题。
API : API Version 12 Beta5
Dev : 5.0.3.700
一、基础
先熟悉几个File文件操作的方法。
- 判断文件是否存在:
import fs from '@ohos.file.fs';
//判断文件是否存在
fs.access(filePath).then((res: boolean) => {
if (res) {
Log.info("文件存在")
} else {
Log.info("文件不存在")
}
}).catch((err: BusinessError) => {
Log.error("access failed with error message: " + err.message + ", error code: " + err.code);
});
- 删除文件:
import fs from '@ohos.file.fs';
fs.unlinkSync(filePath)
- 获取文件长度:
import fs from '@ohos.file.fs';
fs.lstatSync(filePath).size
二、工具类封装
因考虑到可能下载文件会出现在多线程场景,并没有写成单例,可根据需求修改。
LoadingDialog:https://ohpm.openharmony.cn/#/cn/detail/@lyb%2Floading-dialog
import { common } from '@kit.AbilityKit';
import fs from '@ohos.file.fs';
import { BusinessError, request } from '@kit.BasicServicesKit';
import { Log } from './Log';
import { fileIo, picker } from '@kit.CoreFileKit';
import { promptAction } from '@kit.ArkUI';
import LoadingDialog from '@lyb/loading-dialog';
/**
* 下载文件及打开工具类
*/
export class DownloadFileUtil {
/**
* 开始下载文件 设置文件下载路径 校验文件是否存在
*/
startDownFile(downPath: string) {
let pathList = downPath.split("/")
//文件名称
let fileName = pathList[pathList.length-1]
let context = getContext(this) as common.UIAbilityContext;
//文件保存在应用沙箱路径
let filePath = context.filesDir + fileName
Log.info("文件路径:"+filePath)
Log.info("下载地址:"+downPath)
try {
fs.access(filePath).then((res: boolean) => {
if (res) {
Log.info("文件存在")
fs.unlinkSync(filePath)
this.downloadFile(context, downPath, filePath, fileName)
} else {
Log.info("文件不存在")
this.downloadFile(context, downPath, filePath, fileName)
}
}).catch((err: BusinessError) => {
Log.error("access failed with error message: " + err.message + ", error code: " + err.code);
});
} catch (error) {
let err: BusinessError = error as BusinessError;
Log.error("startDownFile:"+err.message)
}
}
/**
* 下载文件
* @param downPath 下载地址
* @param filePath 下载保存路径
* @param fileName 文件名称
*/
downloadFile(context: Context, downPath: string, filePath: string, fileName: string) {
LoadingDialog.showLoading("下载中...")
request.downloadFile(context, {
url: downPath,
filePath: filePath
}).then((downloadTask: request.DownloadTask) => {
let progressCallback = (receivedSize: number, totalSize: number) => {
Log.info("download receivedSize:" + receivedSize + " totalSize:" + totalSize);
};
downloadTask.on('progress', progressCallback);
downloadTask.on('complete', () => {
LoadingDialog.hide()
Log.info('download complete');
Log.error("文件大小:" + fs.lstatSync(filePath).size) //看看文件是否下载正常
this.savePath(filePath, fileName)
})
}).catch((err: BusinessError) => {
LoadingDialog.hide()
Log.error(`Invoke downloadTask failed, code is ${err.code}, message is ${err.message}`);
});
}
/**
* 保存文件
* @param filePath 应用沙箱文件地址
* @param fileName 文件名称
*/
savePath(filePath: string, fileName: string) {
try {
let uri: string = '';
let DocumentSaveOptions = new picker.DocumentSaveOptions();
DocumentSaveOptions.newFileNames = [fileName];
let documentPicker = new picker.DocumentViewPicker();
//调用API拉起保存功能
documentPicker.save(DocumentSaveOptions).then((DocumentSaveResult: Array<string>) => {
uri = DocumentSaveResult[0];
let downFile = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE);
let file = fileIo.openSync(uri, fileIo.OpenMode.READ_WRITE);
Log.info("下载文件路径:" + downFile.path + ",用户地址:" + file.path)
fileIo.copyFile(downFile.path, file.path).then(() => {
promptAction.showToast({ message: "保存成功" })
fileIo.closeSync(file.fd);
fileIo.closeSync(downFile.fd);
}).catch(() => {
promptAction.showToast({ message: "保存失败" })
fileIo.closeSync(file.fd);
fileIo.closeSync(downFile.fd);
}
}).catch((err: BusinessError) => {
Log.error('DocumentViewPicker.save failed with err: ' + JSON.stringify(err));
});
} catch (error) {
let err: BusinessError = error as BusinessError;
Log.error('DocumentViewPicker failed with err: ' + err.message);
}
}
}
三、总结
鸿蒙文件处理这块还是相对复杂,很多API根据需求继续研究【文件管理】。
最后,有个需求希望大家给个建议:我想在线预览word、pdf、ppt、Excel等文件,各位同仁有好的建议评论区回复我,感谢~