簡體   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