Capacitor Ionic应用写入大PDF时Filesystem.writeFile()崩溃求解决方案
解决Ionic/Capacitor写入大PDF文件崩溃问题
问题根源
你当前的实现通过FileReader将Blob转为base64字符串后写入文件,大体积PDF会触发内存过载崩溃:
- base64编码会让原数据体积膨胀33%左右,大文件(如50MB+)转码后会占用大量连续内存空间
- 移动端App内存限制严格,一次性加载并处理整个大文件容易超出阈值
可行解决方案
方案1:直接写入Blob(推荐,Capacitor 3+支持)
Capacitor 3及以上版本的Filesystem.writeFile支持直接传入Blob,无需转base64,大幅降低内存占用:
static async writeAndOpenFile(data: Blob, fileName: string) { try { const result = await Filesystem.writeFile({ path: fileName, data: data, // 直接传入Blob,跳过base64转码 directory: Directory.Data, recursive: true }); const fileOpener = new FileOpener(); await fileOpener.open(result.uri, data.type); console.log('File is opened'); } catch (e) { console.error('Error handling file:', e); } }
方案2:分块读写大文件(兼容旧版Capacitor)
如果必须使用base64转码,通过分块处理避免一次性加载整个文件到内存:
static async writeAndOpenFile(data: Blob, fileName: string) { const chunkSize = 1024 * 1024; // 按1MB分块处理 const totalChunks = Math.ceil(data.size / chunkSize); let offset = 0; try { // 先创建空文件 await Filesystem.writeFile({ path: fileName, data: '', directory: Directory.Data, recursive: true, append: false }); // 逐块写入 for (let i = 0; i < totalChunks; i++) { const chunk = data.slice(offset, offset + chunkSize); const base64Chunk = await this.blobToBase64(chunk); await Filesystem.writeFile({ path: fileName, data: base64Chunk, directory: Directory.Data, append: true // 启用追加模式 }); offset += chunkSize; } // 获取文件URI并打开 const fileUri = await Filesystem.getUri({ path: fileName, directory: Directory.Data }); const fileOpener = new FileOpener(); await fileOpener.open(fileUri.uri, data.type); console.log('File is opened'); } catch (e) { console.error('Error handling file:', e); } } // 封装Blob转base64的Promise方法 private static blobToBase64(blob: Blob): Promise<string> { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(reader.result as string); reader.onerror = reject; reader.readAsDataURL(blob); }); }
方案3:内存优化补充
- 手动释放引用:文件操作完成后,将Blob对象置为
null,帮助垃圾回收:data = null; // 释放Blob内存 - 更换存储目录:尝试将文件写入
Directory.Documents,部分平台对该目录的内存限制更宽松 - 更新插件版本:确保
@capacitor/filesystem和cordova-plugin-file-opener2是最新版本,新版本修复了不少内存泄漏问题
内容的提问来源于stack exchange,提问作者pilotman
相关产品推荐
相关产品推荐

