索引数据库保存范围为

IndexedDB Save range as

本文关键字:范围 保存 数据库 索引      更新时间:2023-09-26

好的,所以我是IndexedDB的新手,对Javascript不是特别有经验。现在,我已经有代码工作,以便用户可以浏览到其文件系统上的文件,并且在选择时,该文件被分解为块(通过使用切片),这些块被转换为十六进制字符串,字符串(以及键)存储在 IndexedDB 中。

这种模式的好处是用户可以选择一个非常大的文件,而且,由于我使用了正确的结构,因此不必一次将整个文件全部加载到内存中。

现在,我正在尝试读回这些十六进制字符串,并在用户单击按钮时让浏览器弹出"另存为"对话框。问题是我还没有设法找到一种方法将数据从 IndexedDB "流式传输"到另存为输入中。你们中有人知道一种方法吗?我这边

就要短了。

谢谢

IndexedDB 不能对记录进行部分(或投影)读/写。文件系统 API 似乎很可能,因为它适用于像对大文件进行顺序查找这样的用例,但我不确定。

你可能想看看最近的讨论,IndexedDB,Blobs和部分Blob - 大文件。他们还讨论了有关您的问题的解决方法。

所以我也希望这样做,并将随着实施的进行更新这个答案。

这个想法是在索引数据库中创建两个实体类型。

  1. 文件

对于存储在索引数据库中的每个文件,文件实体中都会有一个条目。

文件的内容将存储在页面实体中。内容将被拆分为"页面",其中每个页面都是一些(任意)固定大小,例如 16KB。

我的代码将用dart编写(交叉编译为javascript),但逻辑应该很容易直接移植到js。

我将创建一个类,该类将像随机访问文件一样运行。

注意:此时这只是伪代码。

  class RandomAccessFile {
       const int pageSize = 16192;
       int offset = 0;
       int page = 0;
       int inPageOffset = 0;
       List<int> currentPageData;
       String pathToFile;
       late int fileSize;
       RandomAccessFile(this.pathToFile)
       {
          var file = indexDb.read('File', this.pathToFile);
          this.fileSize = file.size;
       }
       void seekTo(int offset)
       {
          this.offset = offset;
          this.page = offset/pageSize;
          this.inPageOffset = offset % pageSize;
        }    
      Stream<int> read() async * {
      { 
         
         _loadPage();
         while (this.offset < fileSize)
         {
             
             while (this.inPageOffset < currentPageData.length) 
             {  
                  yield currentPageData[this.inPageOffset++];
             }
             _loadNextPage()
         }
      }
      void _loadPage()
      {
          currentPageData =  indexDb.read('Page', where file = pathTofile and pageNo = page);
          pageOffset = 0;
       }
  void _loadNextPage()
      {
         page++;
         _loadPage();
           
       }
}