在移动应用开发中,文件上传下载是最基础却最具挑战的功能之一。鸿蒙Next通过其强大的分布式能力和优化的网络框架,为开发者提供了一套完整、高效、安全的文件传输解决方案。
鸿蒙Next文件传输架构概览
鸿蒙Next的文件传输能力主要基于@ohos.request
模块,提供了统一的上传下载接口。与此同时,华为还提供了云存储服务,能够将应用数据安全地存储到云端,实现多设备间的自动同步。
核心特性优势
-
跨设备同步:数据在设备和云端实时同步
-
权限精细控制:精确到每个文件的访问权限
-
大文件支持:单个文件最大支持1GB上传
-
断点续传:大文件上传会自动断点续传,最多重试5次
-
后台传输:支持后台任务模式,不影响用户体验
文件上传实战指南
基础文件上传
在鸿蒙Next中,文件上传可以使用request.uploadFile
方法。需要注意的是,上传前需要把文件复制到cache目录中,然后通过internal://
协议执行操作。
typescript
import request from '@ohos.request';
import fs from '@ohos.fileSystem';
async function uploadFile(localPath: string, serverUrl: string): Promise<void> {
try {
// 准备上传请求的参数
const options = {
url: serverUrl,
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data',
},
files: [
{
filename: 'example.txt',
name: 'file',
uri: localPath, // 需要使用 internal:// 协议路径:cite[1]
type: 'text/plain'
}
]
};
// 发起文件上传请求
const response = await request.upload(options);
if (response && response.responseCode === 200) {
console.info('File uploaded successfully');
} else {
console.error('File upload failed');
}
} catch (error) {
console.error('Error during file upload: ' + error.message);
}
}
云存储上传示例
除了基本的HTTP上传,鸿蒙还提供了更高级的云存储服务:
typescript
// 1. 获取本地文件路径(示例为沙箱路径)
let localPath = "internal://app/files/photo.jpg";
// 2. 创建云存储实例
const storage = new Storage();
// 3. 执行上传(带进度回调)
try {
const uploadResult = await storage.upload({
localPath: localPath,
cloudPath: "user_uploads/2023/photo.jpg",
onUploadProgress: (progress) => {
console.log(`已传 ${progress.loaded} / 总 ${progress.total}`);
}
});
// 4. 处理结果
console.log(`上传成功!实际传输量:${uploadResult.bytesTransferred}`);
} catch (error) {
console.error("上传失败:", error);
}
文件下载完整解决方案
多文件下载监听
鸿蒙Next的@ohos.request
模块中的request.downloadFile
方法可以用于文件下载,并且支持多文件下载监听,能够监听每个文件下载任务的进度、暂停、完成等状态。
typescript
import request from '@ohos.request';
async function downloadFile(downloadUrl: string, savePath: string): Promise<void> {
// 配置下载参数
let config: request.agent.Config = {
action: request.agent.Action.DOWNLOAD, // 配置任务选项,这里配置为下载任务
url: downloadUrl, // 配置下载任务url
overwrite: true, // 下载过程中路径已存在时的解决方案选择。true表示覆盖已存在的文件
method: 'GET', // HTTP标准方法。下载时,使用GET或POST。
saveas: './', // 这里'./'表示下载至应用当前缓存路径下:cite[6]。
mode: request.agent.Mode.BACKGROUND, // 任务模式设置后台任务:cite[6]。
gauge: true // 后台任务的过程进度通知策略:cite[6]。
};
try {
// 创建下载任务
const task: request.agent.Task = await request.agent.create(context, config);
// 注册下载任务相关回调
task.on('completed', () => {
console.info('Download completed');
});
task.on('failed', (err: BusinessError) => {
console.error(`Download failed: ${err.message}`);
});
task.on('progress', (progress: request.agent.Progress) => {
console.log(`下载进度:${(progress.loaded/progress.total*100).toFixed(1)}%`);
});
// 启动下载任务
task.start((err: BusinessError) => {
if (err) {
console.error(`Failed to start download: ${err.message}`);
return;
}
console.info('Download started successfully');
});
} catch (error) {
console.error(`Download creation error: ${error.message}`);
}
}
云存储下载
使用云存储服务下载文件更加简便:
typescript
// 下载到沙箱的downloads目录
let savePath = "internal://app/downloads/demo.jpg";
const downloadResult = await storage.download({
cloudPath: "user_uploads/2023/photo.jpg",
localPath: savePath,
onDownloadProgress: (progress) => {
console.log(`下载进度:${(progress.loaded/progress.total*100).toFixed(1)}%`);
}
});
console.log(`文件已保存到:${savePath}`);
高级功能与性能优化
多文件下载管理
在实际应用中,经常需要同时管理多个文件下载任务。鸿蒙Next允许创建多个下载监听实例,每个实例管理一个文件的下载任务。
typescript
// 创建多个文件下载监听实例
ForEach(this.downloadConfigArray, (item: request.agent.Config) => {
ListItem() {
// 创建文件下载监听实例
FileDownloadItem({
downloadConfig: item, // 文件下载配置
isStartAllDownload: this.isStartAllDownload, // 是否全部开始下载
downloadCount: this.downloadCount // 待下载任务数量
downloadFailCount: this.downloadFailCount // 下载失败任务数量
})
}
}, (item: request.agent.Config) => JSON.stringify(item))
重要提醒:
-
每个应用最多支持创建10个未完成的任务
-
下载路径必须位于应用沙箱内
-
可通过
getFileHash()
校验文件完整性 -
使用前检查本地存储空间是否充足
性能优化要点
-
进度回调优化:注册了progress下载进度更新监听时,不建议在下载进度更新回调中加日志打印,以减少不必要的性能损耗。
-
网络重试策略 :
request.agent.Config
的retry
参数默认是true,当没有网络或者网络不满足时,会自动暂停等待。如果希望无网络时直接失败而不是暂停,可以将retry设置为false。 -
大文件处理:对于大文件,建议使用URI引用而非直接写入二进制数据,避免内存溢出。
权限配置与安全考量
必要权限声明
在module.json5
文件中配置必要的权限:
json
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.INTERNET",
"reason": "$string:internet_permission_reason"
},
{
"name": "ohos.permission.READ_MEDIA",
"reason": "$string:read_media_permission_reason"
},
{
"name": "ohos.permission.WRITE_MEDIA",
"reason": "$string:write_media_permission_reason"
}
]
}
}
安全最佳实践
-
沙箱路径使用 :文件路径要用
internal://app/
开头的沙箱路径 -
敏感数据保护:敏感数据建议使用加密存储
-
权限最小化:只申请应用必需的权限,避免过度申请
实战应用场景
场景一:电商应用图片上传
用户上传商品评价图片,需要支持多图上传和进度显示:
typescript
class ProductReview {
async uploadReviewImages(images: string[]): Promise<void> {
const uploadPromises = images.map((imagePath, index) => {
return this.uploadSingleImage(imagePath, `reviews/${Date.now()}_${index}.jpg`);
});
await Promise.all(uploadPromises);
console.info('All review images uploaded successfully');
}
private async uploadSingleImage(imagePath: string, cloudPath: string): Promise<void> {
// 使用云存储上传单个图片
return await storage.upload({
localPath: imagePath,
cloudPath: cloudPath,
onUploadProgress: (progress) => {
// 更新UI进度显示
this.updateProgress(cloudPath, progress.loaded / progress.total);
}
});
}
}
场景二:离线文件批量下载
在WiFi环境下预下载用户可能需要的文件,支持暂停和恢复:
typescript
class OfflineManager {
private downloadQueue: request.agent.Task[] = [];
async addToDownloadQueue(items: DownloadItem[]): Promise<void> {
for (const item of items) {
const config: request.agent.Config = {
action: request.agent.Action.DOWNLOAD,
url: item.url,
saveas: `./downloads/${item.filename}`,
mode: request.agent.Mode.BACKGROUND,
gauge: true
};
const task = await request.agent.create(context, config);
this.setupTaskListeners(task, item.id);
this.downloadQueue.push(task);
}
}
pauseAllDownloads(): void {
this.downloadQueue.forEach(task => {
task.pause();
});
}
resumeAllDownloads(): void {
this.downloadQueue.forEach(task => {
task.resume();
});
}
}
常见问题与解决方案
FAQ
Q: 无网络时点击下载,任务状态显示"已暂停"而不是"下载失败"?
A: 这是因为request.agent.Config
的retry
参数默认为true。当没有网络时,系统会自动暂停任务等待网络恢复。如果希望直接显示失败,可以将retry设置为false。
Q: 上传文件时遇到权限问题?
A: 确保在config.json
中添加了ohos.permission.READ_MEDIA
等必要权限,并且文件路径使用internal://app/
开头的沙箱路径。
Q: 如何实现跨设备文件同步?
A: 使用鸿蒙云存储服务,它能自动将数据在设备和云端实时同步。
结语
鸿蒙Next的文件上传下载功能通过@ohos.request
模块和云存储服务,为开发者提供了一套完整、高效的解决方案。无论是简单的单文件传输,还是复杂的多文件后台下载,鸿蒙都提供了相应的API支持。
关键优势总结:
-
简单易用:清晰的API设计,快速上手
-
功能丰富:支持进度监控、断点续传、后台传输等高级特性
-
安全可靠:沙箱机制和权限控制保障数据安全
-
跨端同步:云存储服务实现多设备数据同步
掌握鸿蒙Next的文件传输能力,能够帮助开发者构建出体验更加优秀的应用程序,在万物互联的时代提供无缝的数据流转体验。