You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ionic 6 Capacitor写入ZIP内SQLite文件到Documents目录报错排查

问题根因
  • 二进制文件读取逻辑错误:.sqlite 属于二进制格式文件,原有代码使用 compressedFile.async('string') 读取会直接破坏二进制字节结构,不仅会导致文件损坏,乱码字节还会触发写入校验失败。
  • Capacitor Filesystem 插件使用方式错误:该插件并非不支持二进制文件写入,只是要求二进制内容转为Base64格式字符串传入,同时指定对应编码参数即可,无需额外引入Cordova生态的文件插件。
  • 路径参数配置隐患:原有写入方法recursive设为false,如果压缩包内存在多层子目录,会因为父目录未创建直接抛出写入失败错误。
可直接运行的修复方案

1. 新增ArrayBuffer转Base64工具方法

该方法兼容iOS与Electron环境,无额外依赖:

private arrayBufferToBase64(buffer: ArrayBuffer): string {
  const bytes = new Uint8Array(buffer);
  let binaryStr = '';
  for (let i = 0; i < bytes.byteLength; i++) {
    binaryStr += String.fromCharCode(bytes[i]);
  }
  return window.btoa(binaryStr);
}

2. 修改JSZip解压读取逻辑

二进制文件统一读取为ArrayBuffer格式,转Base64后再传入写入方法,禁止用string模式读取二进制文件:

public async unzipFolder(file: File): Promise<string[]> {
  const zip: JSZip = await JSZip.loadAsync(file);
  const promises: Promise<string>[] = [];

  zip.forEach((relativePath: string, zipFile: JSZipObject) => {
    // 跳过目录项,只处理文件
    if (!zipFile.dir) {
      promises.push(this.unzipFile(zipFile));
    }
  });
  return await Promise.all(promises);
}

public async unzipFile(compressedFile: JSZipObject): Promise<string> {
  // 统一用arraybuffer模式读取,兼容文本、二进制所有类型文件
  const fileBuffer = await compressedFile.async('arraybuffer');
  const base64Data = this.arrayBufferToBase64(fileBuffer);
  return this.fileOpsService.write(compressedFile.name, base64Data);
}

3. 修改Capacitor Filesystem写入逻辑

显式指定Base64编码,开启递归创建目录:

import { Filesystem, Directory, Encoding, WriteFileResult } from '@capacitor/filesystem';

public async write(
  path: string,
  data: string,
  directory: Directory = Directory.Documents
): Promise<WriteFileResult> {
  return await Filesystem.writeFile({
    path: path,
    directory: directory,
    data: data,
    recursive: true,
    // 二进制文件写入必须指定Base64编码
    encoding: Encoding.Base64
  });
}
之前尝试方案无效的原因说明
  • 读取为ArrayBuffer/Blob格式无效:是因为没有将二进制内容转为Base64字符串传入,Capacitor Filesystem插件不支持直接接收ArrayBuffer/Blob类型参数,仅接受字符串格式的内容。
  • 修改编码为UTF-8/UTF-16/ASCII无效:这类编码仅适用于纯文本文件,二进制文件必须使用Base64编码传入才能保证字节信息不丢失。
  • Cordova File插件报错:Capacitor环境对Cordova插件的文件沙箱路径做了隔离,直接调用会出现路径映射不匹配问题,且XCode中抛出的QLThumbnailErrorDomain日志属于系统选择文件时的缩略图关联警告,和写入失败无直接关联,可直接忽略。
平台适配说明
  • iOS端:Capacitor默认拥有Documents目录的读写权限,无需额外配置权限描述文件,写入的sqlite文件可直接被相关sqlite插件读取。
  • Electron端:上述代码可直接运行,文件会默认存储到Electron应用对应的用户文档目录下,无需额外适配。

内容的提问来源于stack exchange,提问作者N0M4D

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 10:24:22