兄弟们,我在看掘金的时候找到分片上传失败的原因了,就很小的一个点:
html5Plus 的文档写的不太清楚出了,很多地方让人猜。就比如File.slice(start,end) ,在js中slice截取不包含end,但在Html5Plus File.slice包含end,导致合并文件后总是比原文件大一点。
也就是使用Html5Plus的File.slice方法:每个分片end-1。
已经在安卓模拟器上测试,并对比MD5值。
因为没有 readAsArrayBuffer 方法,只能通过 Base64 转 ArrayBuffer,需要注意去除dataUrl头部
关键代码
const readFileChunk = (file, start, end) => {
return new Promise((resolve, reject) => {
try {
const reader = new plus.io.FileReader();
reader.onload = () => {
try {
// 排除base64头部
const base64 = reader.result.substring(reader.result.indexOf(',') 1);
resolve(uni.base64ToArrayBuffer(base64));
} catch (e) {
reject(e)
}
};
reader.onerror = reject;
// 使用slice方法读取指定范围, 需要注意: end 包含
const blob = file.slice(start, end);
reader.readAsDataURL(blob); // HTML5 需要转换为base64读取
} catch (e) {
reject(e)
}
});
};
完整的分片上传
async uploadMultipart(filePath, chunkSize = 1024 * 1024 * 5) {
// 通过文件路径获取File对象(Html5Plus的File)
const file = await getFile(filePath);
const uploadId = await multipartUploadApi.startMultipart(file.name)
// console.log('uploadId', uploadId)
const partList = []
const totalSize = file.size;
for (let i = 0; i < totalSize / chunkSize; i ) {
const start = i * chunkSize;
const end = Math.min((i 1) * chunkSize - 1, totalSize);
const chunkBuffer = await readFileChunk(file, start, end);
const partItem = await multipartUploadApi.uploadPart(uploadId, i 1, chunkBuffer)
partList.push(partItem)
}
const result = await multipartUploadApi.complete(uploadId, partList)
return result
},
getFile(filePath) {
return new Promise((resolve, reject) => {
plus.io.resolveLocalFileSystemURL(filePath, (entry) => {
if (!entry.isFile) {
reject(new Error(`不是文件:${filePath}`))
return
}
entry.file((file) => {
resolve(file)
}, (err) => {
// console.log('无法获取文件')
reject(err)
})
}, (error) => {
// console.log('文件不存在', error)
reject(error)
})
})
},
readFileChunk (file, start, end) {
return new Promise((resolve, reject) => {
try {
const reader = new plus.io.FileReader();
reader.onload = () => {
try {
// 排除base64头部
const base64 = reader.result.substring(reader.result.indexOf(',') 1);
resolve(uni.base64ToArrayBuffer(base64));
} catch (e) {
reject(e)
}
};
reader.onerror = reject;
// 使用slice方法读取指定范围, 需要注意: end 包含
const blob = file.slice(start, end);
reader.readAsDataURL(blob); // HTML5 需要转换为base64读取
} catch (e) {
reject(e)
}
});
};
参考的掘金文章:
解决Uniapp中文件切片问题
作者:Synmbrf
链接:https://juejin.cn/post/7493783786707058726
来源:稀土掘金
0 个评论
要回复文章请先登录或注册