ReactNativeBlobUtil在Android处理大文件转base64时崩溃求助
Android下ReactNativeBlobUtil转Base64处理40MB PDF崩溃问题
问题场景
使用ReactNativeBlobUtil获取PDF并转Base64时,iOS端处理100MB文件正常,但Android端处理40MB文件时,调用bookResponse.base64()直接崩溃。相关代码如下:
ReactNativeBlobUtil.config({ fileCache: false, }) .fetch('GET', response?.data?.url) .then(async bookResponse => { const content = await bookResponse.base64(); // 此行导致Android崩溃 // 将内容拆分为8MB块 const splittedContent = splitBase64IntoChunks(content); // ...后续代码 });
崩溃原因
Android的内存管控比iOS严格,Base64编码会让文件体积增加约33%(40MB原文件转完约53MB),加上fileCache: false会把整个文件直接加载到内存,远超React Native JS引擎(如Hermes)的内存阈值,触发OOM(内存不足)崩溃。
解决方案
核心思路是避免一次性把整个文件加载到内存,改用磁盘缓存+分块读取的方式处理:
1. 启用文件缓存+分块读取转Base64
修改配置启用磁盘缓存,再通过文件流分块读取内容并转Base64,每块仅占用少量内存:
ReactNativeBlobUtil.config({ fileCache: true, // 开启文件缓存,将文件保存到本地磁盘 }) .fetch('GET', response?.data?.url) .then(async bookResponse => { const filePath = bookResponse.path(); const base64Chunks = []; // 创建读取流,按8MB块读取并直接返回Base64格式 const stream = ReactNativeBlobUtil.readStream( filePath, 'base64', 8 * 1024 * 1024 // 和你之前的块大小保持一致 ); return new Promise((resolve, reject) => { stream.open(); // 读取到块数据时存入数组 stream.onData(chunk => base64Chunks.push(chunk)); // 处理流错误 stream.onError(err => { stream.close(); reject(err); }); // 读取完成后拼接所有块 stream.onEnd(() => { stream.close(); const fullBase64 = base64Chunks.join(''); const splittedContent = splitBase64IntoChunks(fullBase64); // ...后续业务处理 resolve(splittedContent); }); }); }) .catch(err => console.error('处理失败:', err));
2. 可选:清理临时缓存文件
处理完成后,若不需要保留缓存文件,可调用bookResponse.flush()删除:
// 在onEnd或处理完成后执行 await bookResponse.flush();
补充说明
- Android端需确保应用拥有临时文件存储权限(ReactNativeBlobUtil默认会处理临时目录权限,无需额外申请);
- 分块读取的大小可根据实际内存情况调整,8MB是比较均衡的选择,避免块太小导致IO频繁,或块太大占用过多内存。
内容的提问来源于stack exchange,提问作者batuhanors
相关产品推荐
相关产品推荐

