uni-app 【报Bug】new plus.io.FileReader > reader.readAsDataURL(file)转码后输出不完整(包括图片,音频)
uni-app 【报Bug】new plus.io.FileReader > reader.readAsDataURL(file)转码后输出不完整(包括图片,音频)
操作步骤:
- 通过5+获取指定文件并转码。
预期结果:
- 转码后的base64能完整演示
实际结果:
- 转码后的base64 能演示,但有出现断层。如音频mp3文件拿到base64后播放时出现卡顿,少帧,图片拿到base64后演示不完整。
bug描述:
- 按照HTML5+ IO操作获取文件信息后通过new plus.io.FileReader() > reader.readAsDataURL(file) 编码后信息不完整,已测试图片,音频文件

更多关于uni-app 【报Bug】new plus.io.FileReader > reader.readAsDataURL(file)转码后输出不完整(包括图片,音频)的实战教程也可以访问 https://www.itying.com/category-93-b0.html
哪个平台?
更多关于uni-app 【报Bug】new plus.io.FileReader > reader.readAsDataURL(file)转码后输出不完整(包括图片,音频)的实战教程也可以访问 https://www.itying.com/category-93-b0.html
app
回复 1***@qq.com: 。。。问题是Android 还是 iOS ,HX使用的版本是多少,具体哪个机型,还是所有机型 【正确报bug的姿势】https://ask.dcloud.net.cn/article/38139
这是转码后的base64,在电脑上播放失败
用 entry.file 的得到的file对象 不是继承自 blob 与普通的h5 不一致 而且io.fileReader readAsDataURL方法 得到的音频视频 无法播放
请问解决了吗?
根据你提供的信息,这确实是uni-app/5+环境中一个已知的文件读取问题。plus.io.FileReader的readAsDataURL方法在处理较大文件或特定格式时,确实可能出现数据截断或编码不完整的情况。
主要原因分析:
- 5+底层实现限制:
plus.io.FileReader是HTML5+规范中的API,其底层实现(特别是在Android平台)对一次性读取大文件到内存并转换为Base64可能存在缓冲区限制或编码处理缺陷。 - Base64编码内存开销:Base64编码会使数据体积增加约33%。对于较大的音频或图片文件,在内存中进行完整的转换与拼接可能出现问题。
- 异步处理机制不完善:该API在文件读取与编码完成的回调触发时,数据可能尚未完全准备就绪。
建议的解决方案:
方案一:使用分片读取(推荐用于大文件)
对于大文件,避免一次性读取。可以使用plus.io.File的slice方法分片读取后,手动拼接Base64。
function readFileAsDataURL(filePath) {
return new Promise((resolve, reject) => {
plus.io.resolveLocalFileSystemURL(filePath, (entry) => {
entry.file((file) => {
const chunkSize = 1024 * 512; // 512KB分片
const chunks = Math.ceil(file.size / chunkSize);
let currentChunk = 0;
let base64Data = '';
function readChunk() {
const start = currentChunk * chunkSize;
const end = Math.min(start + chunkSize, file.size);
const blob = file.slice(start, end);
const reader = new plus.io.FileReader();
reader.onload = (e) => {
// 移除dataURL前缀,只保留Base64数据
const chunkData = e.target.result.split(',')[1];
base64Data += chunkData;
currentChunk++;
if (currentChunk < chunks) {
readChunk();
} else {
resolve(`data:${file.type};base64,${base64Data}`);
}
};
reader.onerror = reject;
reader.readAsDataURL(blob);
}
readChunk();
}, reject);
}, reject);
});
}
方案二:使用ArrayBuffer手动转换 先读取为ArrayBuffer,再手动转换为Base64,避免API内部转换问题:
function fileToBase64(filePath) {
return new Promise((resolve, reject) => {
plus.io.resolveLocalFileSystemURL(filePath, (entry) => {
entry.file((file) => {
const reader = new plus.io.FileReader();
reader.onload = (e) => {
const arrayBuffer = e.target.result;
const base64 = btoa(
new Uint8Array(arrayBuffer).reduce(
(data, byte) => data + String.fromCharCode(byte),
''
)
);
resolve(`data:${file.type};base64,${base64}`);
};
reader.onerror = reject;
reader.readAsArrayBuffer(file);
}, reject);
}, reject);
});
}
方案三:使用uni-app API替代 如果文件在项目目录中,优先使用uni-app的API:
// 对于项目静态资源
const base64 = await uni.getFileSystemManager().readFileSync(filePath, 'base64');
// 对于选择文件
uni.chooseFile({
success: (res) => {
const tempFilePath = res.tempFilePaths[0];
const base64 = await uni.getFileSystemManager().readFileSync(tempFilePath, 'base64');
}
});
临时规避方案: 对于小文件,可以尝试先转换为Blob URL直接使用,避免Base64转换:
const objectURL = URL.createObjectURL(file);
// 使用objectURL作为音视频源或图片源

