Reading a text file from the client and on the client that exceeds the maximum size of a single string in javascript

后端 未结 1 1702
旧时难觅i
旧时难觅i 2021-01-25 01:38

I\'d like to reverse the following steps performed on the client in javascript but am having trouble with the blob.

In an indexedDB database, over an open cursor on an o

1条回答
  •  长情又很酷
    2021-01-25 02:01

    Funnilly enough you already said in your question what should be done:

    Slice your Blob.

    The Blob interface does have a .slice() method.
    But to use it, you should keep track of the positions where your merging occurred. (could be in an other field of your db, or even as an header of your file:

    function readChunks({blob, chunk_size}) {
      console.log('full Blob size', blob.size);
      const strings = [];  
      const reader = new FileReader();
      var cursor = 0;
      reader.onload = onsingleprocessed;
      
      readNext();
      
      function readNext() {
        // here is the magic
        const nextChunk = blob.slice(cursor, (cursor + chunk_size));
        cursor += chunk_size;
        reader.readAsText(nextChunk);
      }
      function onsingleprocessed() {
        strings.push(reader.result);
        if(cursor < blob.size) readNext();
        else {
          console.log('read %s chunks', strings.length);
          console.log('excerpt content of the first chunk',
            strings[0].substring(0, 30));
        }
      }
    }
    
    
    
    // we will do the demo in a Worker to not kill visitors page
    function worker_script() {
      self.onmessage = e => {
        const blobs = [];
        const chunk_size = 1024*1024; // 1MB per chunk
        for(let i=0; i<500; i++) {
          let arr = new Uint8Array(chunk_size);
          arr.fill(97); // only 'a'
          blobs.push(new Blob([arr], {type:'text/plain'}));
        }
        const merged = new Blob(blobs, {type: 'text/plain'});
        self.postMessage({blob: merged, chunk_size: chunk_size});
      }
    }
    const worker_url = URL.createObjectURL(
      new Blob([`(${worker_script.toString()})()`],
        {type: 'application/javascript'}
      )
    );
    const worker = new Worker(worker_url);
    worker.onmessage = e => readChunks(e.data);
    worker.postMessage('do it');

    0 讨论(0)
提交回复
热议问题