繁体   English   中英

Ionic 6 - 电容器文件系统 - 从 ZIP 复制 SQLite 文件

[英]Ionic 6 - Capacitor Filesystem - copy SQLite files from ZIP

大家好,感谢您花时间阅读和回答。

描述

我正在使用Ionic 6Angular 14电容器 我需要复制用户上传的 ZIP 文件的内容(它包含.sqlite 文件),并将其存储在 Documents 文件夹中。 为此,我正在使用JSZip库。

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

    zip.forEach((relativePath: string, zipFile: JSZipObject) =>
        promises.push(this.unzipFile(zipFile));
    );
    return await Promise.all(promises);
  }

  public async unzipFile(compressedFile: JSZipObject): Promise<string> {
    return await compressedFile.async('string').then((data: string) => {
     this.fileOpsService.write(compressedFile.name, data)
    });
  }

这里一切正常。 当我尝试使用Filesystem plugin (capacitor)将其存储在 Documents 文件夹中时出现问题。

  public async write(
    path: string,
    data: string,
    directory: Directory = Directory.Documents
  ): Promise<WriteFileResult> {
    return await Filesystem.writeFile({
      path: path,
      directory: directory,
      data: data,
      recursive: false,
    });
  }

XCode 的终端抛出这个错误:

{"errorMessage":"Unable to save file"}

我尝试了文件插件(awasome-cordova-file),但它不起作用。

  public async write(
    path: string,
    data: ArrayBuffer,
    directory: Directory = Directory.Documents
  ): Promise<any> {
    return await File.writeFile(path, '', data, {replace: true})
  }

它引发下一个错误:

[DocumentManager] Failed to associate thumbnails for picked URL file:///private/var/mobile/Containers/Shared/AppGroup/XXX/File%20Provider%20Storage/TEST_BATCH2.zip with the Inbox copy file:///private/var/mobile/Containers/Data/Application/XXX/tmp/io.ionic.starter.ivan-Inbox/TEST_BATCH2.zip: Error Domain=QLThumbnailErrorDomain Code=102 "(null)" UserInfo={NSUnderlyingError=0x282532cd0 {Error Domain=GSLibraryErrorDomain Code=3 "Generation not found" UserInfo={NSDescription=Generation not found}}}

经过测试的解决方案

  1. 我尝试将 ZIP 文件读取为 ArrayBuffer 或 Blob ,但 Filesystem 插件只能使用字符串数据,所以它不起作用。
  2. 我还尝试将 Filesystem的编码值更改为 UTF-8、UTF-16 和 ASCII,但没有成功。 默认值为 Base64 编码。
  3. 我尝试使用 cordoba File 插件 在以前的应用程序版本中,这工作正常,所以我尝试了一下(当应用程序使用 cordoba 代替电容器时)。 没用。

理论

  1. 我不确定这里发生了什么,但似乎可能与编码有关。 我想文件系统不是设计的 4 个副本 .sqlite 文件。
  2. 也许与相对路径有关,但我不这么认为。
  3. 一些Apple sh*t,你知道...

笔记

  1. 我只需要它在 iOS 和 Electron 平台上工作。 浏览器可能是一个加号,但不是必需的。
  2. 我知道 API/REST 方法可能会更好,但对于这个应用程序来说是不可行的。 我们需要将数据存储在本地。

好的。 几天后,我终于找到了解决方案。 这是它,如果它可以帮助任何人......

我通过将 'string' 替换为 'blob' 更改了从 ZIP 文件中读取的方式,如您在以下代码段中所见:

  public async unzipFile(compressedFile: JSZipObject): Promise<void> {
    return await compressedFile.async('blob').then(async (data: Blob) => {
      const filename: string = compressedFile.name
        .replace('.sqlite', 'SQLite.db');
      const base64 = await this.convertBlobToBase64(data);
      this.fileOpsService.write(filename, base64);
    });
  }

我创建了一个如下所示的 convertBlobToBase64 辅助函数:

  private convertBlobToBase64 = (blob: Blob) => new Promise((resolve, reject) => {
    const reader: FileReader = new FileReader();
    reader.onerror = reject;
    reader.onload = () => {
      resolve(reader.result);
    }
    reader.readAsDataURL(blob);
  })

它有效! 请注意,我替换了文件名,因为我需要以这种格式使用另一个插件来读取它=)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM