1. 文件选择API对比分析
在开发App端文件选择功能时,开发者通常会面临多种API选择。本文将深入分析三种主要的文件选择方式:uni.chooseMedia、uni.chooseFile和plus.gallery.pick,并基于实际项目需求提供最佳实践建议。
1.1 uni.chooseMedia
uni.chooseMedia是UniApp推荐的现代化媒体文件选择API,专为选择图片和视频而设计。
特点:
javascript
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,理论上可以用于选择任意类型的文件。
特点:
javascript
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,提供了最底层的文件访问能力。
特点:
javascript
plus.gallery.pick(
(e) => {
const filePath = e.files[0];
// 处理文件路径
},
(e) => {
// 错误处理
}, {
filter: "none",
multiple: false,
maximum: 1
}
);
优势:
- 底层控制:提供最精细的控制选项
- 高兼容性:在App平台有良好的支持
- 功能完整:支持多种过滤和选择模式
限制:
- 平台限定:仅在App平台可用
- 复杂性:API相对复杂,需要处理更多细节
- 非标准化:不是UniApp标准API
2. 文件管理及存储实现
2.1 本地文件保存机制
javascript
// 保存文件到本地
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 本地文件列表管理
javascript
// 加载本地文件列表
loadLocalFiles() {
uni.getSavedFileList({
success: (res) => {
this.localFiles = res.fileList || [];
console.log('刷新本地文件列表成功', res);
},
fail: () => {
this.localFiles = [];
}
});
}
使用uni.getSavedFileList获取所有通过uni.saveFile保存的文件列表,实现统一管理。
2.4 文件缓存机制
javascript
// 保存文件记录到缓存
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. 数据持久性
持久性存储:
- 数据在应用重启后仍然存在
- 数据在设备重启后仍然存在
- 数据不会因为应用进入后台而丢失
清空时机:
-
用户手动清除:
javascript// 主动清空所有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. 合理使用存储空间:
javascript
// 定期清理过期数据
function cleanExpiredStorage() {
uni.getStorageInfo({
success: (res) => {
console.log('当前存储大小:', res.currentSize, 'KB');
// 如果超过一定大小,清理旧数据
if (res.currentSize > 10240) { // 10MB
// 执行清理逻辑
}
}
});
}
2. 数据版本管理:
javascript
// 在应用启动时检查数据版本
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. 敏感数据处理:
javascript
// 对敏感数据进行加密存储
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平台需要最高兼容性
- 需要访问底层文件系统功能