uni-app 开发APP应用媒体处理与文件管理功能
1. 文件选择API对比分析
在开发App端文件选择功能时,开发者通常会面临多种API选择。本文将深入分析三种主要的文件选择方式:uni.chooseMedia、uni.chooseFile和plus.gallery.pick,并基于实际项目需求提供最佳实践建议。
1.1 uni.chooseMedia
uni.chooseMedia是UniApp推荐的现代化媒体文件选择API,专为选择图片和视频而设计。
特点:
uni.chooseMedia({count: 1,mediaType: ['mix'], // 可选值:['image','video', 'mix']  sourceType: ['album', 'camera'],success: (res) => {const file = res.tempFiles[0];// file.tempFilePath, file.size, file.duration等}
});
优势:专为媒体文件选择而优化,同时支持图片和视频选择
限制:
- 仅限媒体文件:不支持选择其他类型文件
- 平台差异:某些平台可能不完全支持所有参数
1.2 uni.chooseFile
uni.chooseFile是UniApp提供的通用文件选择API,理论上可以用于选择任意类型的文件。
特点:
uni.chooseFile({count: 1,extension: [], // 文件类型过滤success: (res) => {const file = res.tempFiles[0];// file.path, file.size, file.name等}
});
优势:
- 通用性强:支持任意类型文件选择
- 类型过滤:可以通过extension参数限制文件类型
- 标准化:UniApp官方API,统一的使用方式
限制:仅支持H5端 !!!
1.3 plus.gallery.pick
plus.gallery.pick是HTML5+规范提供的原生文件选择API,提供了最底层的文件访问能力。
特点:
plus.gallery.pick((e) => {const filePath = e.files[0];// 处理文件路径},(e) => {// 错误处理}, {filter: "none",multiple: false,maximum: 1}
);
优势:
- 底层控制:提供最精细的控制选项
- 高兼容性:在App平台有良好的支持
- 功能完整:支持多种过滤和选择模式
限制:
- 平台限定:仅在App平台可用
- 复杂性:API相对复杂,需要处理更多细节
- 非标准化:不是UniApp标准API
2. 文件管理及存储实现
2.1 本地文件保存机制
// 保存文件到本地
saveFileToLocal() {uni.saveFile({tempFilePath: this.currentFile.path,success: (res) => {this.showMessage('保存文件成功: ', 'success');this.loadLocalFiles(); // 刷新本地文件列表},fail: (err) => {this.showMessage('保存文件失败: ' + (err.errMsg || '未知错误'), 'error');}});
}
通过uni.saveFile将文件存储在自己项目的文件目录下,将相册文件变为项目文件。
2.3 本地文件列表管理
// 加载本地文件列表
loadLocalFiles() {uni.getSavedFileList({success: (res) => {this.localFiles = res.fileList || [];console.log('刷新本地文件列表成功', res);},fail: () => {this.localFiles = [];}});
}
使用uni.getSavedFileList获取所有通过uni.saveFile保存的文件列表,实现统一管理。
2.4 文件缓存机制
// 保存文件记录到缓存
saveFileRecord(filePath) {const fileName = this.getFileName(filePath);uni.getStorage({key: 'local_files_list',success: (res) => {let files = res.data || [];// 检查是否已存在const exists = files.some(file => file === fileName);if (!exists) {files.unshift(fileName); // 添加到开头uni.setStorage({key: 'local_files_list',data: files,success: (res) => {console.log('保存缓存成功', res);this.showMessage('保存缓存成功', 'success');this.viewCacheData();}});} else {this.showMessage('文件名字已存在', 'info');}}});
}
通过Storage机制实现文件名的缓存管理,提供额外的文件索引功能。
2.5 Storage在App端的存储机制
2.5.1. 存储位置
Android平台:
- 存储路径:/data/data/{package_name}/shared_prefs/
- 具体文件:通常存储在以应用包名为前缀的XML文件中
- 存储方式:使用Android的SharedPreferences机制
iOS平台:
- 存储路径:应用沙盒的Library/Preferences目录
- 具体文件:以应用Bundle ID命名的plist文件
- 存储方式:使用iOS的NSUserDefaults机制
2.5.2. 数据持久性
持久性存储:
- 数据在应用重启后仍然存在
- 数据在设备重启后仍然存在
- 数据不会因为应用进入后台而丢失
清空时机:
- 
用户手动清除: // 主动清空所有storage数据 uni.clearStorage({success: () => {console.log('所有storage数据已清空');} });// 删除特定key的数据 uni.removeStorage({key: 'local_files_list',success: () => {console.log('指定数据已清空');} });
- 
应用卸载: - 当用户卸载应用时,所有存储在应用私有目录中的数据都会被系统自动清除
- 这包括SharedPreferences/NSUserDefaults中的数据
 
- 
系统存储空间清理: - 在极少数情况下,系统可能会清理应用数据以释放存储空间
- 但这通常不会影响到SharedPreferences/NSUserDefaults中的数据
 
- 
应用数据清除: - 用户在系统设置中选择"清除应用数据"时
- 所有存储数据会被清空,但应用本身仍保留在设备上
 
2.5.3. 存储容量限制
Android:
- SharedPreferences理论上没有固定大小限制
- 但建议单个key的value不要超过1MB
- 总体受设备存储空间限制
iOS:
- NSUserDefaults建议存储较小的数据(通常<1MB)
- 大量数据应考虑使用其他存储方式
2.5.4. 数据安全性考虑
私有性:
- Storage数据存储在应用私有目录中
- 其他应用无法直接访问这些数据
- 只有当前应用可以读写这些数据
备份考虑:
- 在Android中,SharedPreferences默认会参与系统备份
- 在iOS中,NSUserDefaults也会参与iCloud备份
- 如果存储敏感信息,需要考虑加密处理
2.5.6. 最佳实践建议
1. 合理使用存储空间:
// 定期清理过期数据
function cleanExpiredStorage() {uni.getStorageInfo({success: (res) => {console.log('当前存储大小:', res.currentSize, 'KB');// 如果超过一定大小,清理旧数据if (res.currentSize > 10240) { // 10MB// 执行清理逻辑}}});
}
2. 数据版本管理:
// 在应用启动时检查数据版本
function checkDataVersion() {uni.getStorage({key: 'app_data_version',success: (res) => {const currentVersion = '1.0.0';if (res.data !== currentVersion) {// 数据版本不匹配,可能需要清理或迁移uni.clearStorage();uni.setStorage({key: 'app_data_version',data: currentVersion});}}});
}
3. 敏感数据处理:
// 对敏感数据进行加密存储
function saveSensitiveData(key, data) {// 简单的加密示例(实际项目中应使用更安全的加密算法)const encryptedData = btoa(JSON.stringify(data));uni.setStorage({key: key,data: encryptedData});
}function getSensitiveData(key) {uni.getStorage({key: key,success: (res) => {// 解密数据const decryptedData = JSON.parse(atob(res.data));return decryptedData;}});
}
应用通过uni.setStorage保存的缓存数据:
- 存储位置:应用私有目录中(Android的SharedPreferences,iOS的NSUserDefaults)
- 持久性:应用重启后数据仍然存在
- 清空时机:应用卸载、用户手动清除、主动调用清除API时
- 安全性:数据私有,其他应用无法访问
- 管理建议:定期清理、版本控制、合理使用存储空间
这种存储机制非常适合用于保存文件索引、用户偏好设置等轻量级数据。
3. 推荐使用场景
选择uni.chooseMedia的场景:
- 专门处理图片和视频文件
- 需要获取详细的媒体文件信息
- 追求现代化的用户体验
选择uni.chooseFile的场景:
- 需要选择任意类型的文件
- 可以获取详细的媒体文件信息
- 仅仅只有H5端使用
选择plus.gallery.pick的场景:
- 需要精细控制文件选择行为(可以直接打开视频加图片类型的窗口)
- 在App平台需要最高兼容性
- 需要访问底层文件系统功能
