使文件缓冲区在 Javascript 中的回调函数之外可访问的最佳方法用于大文件?

Best way to make file buffer accessible outside a callback function in Javascript for large files?

我是 JS 新手,我需要加载一个文件 1,将其中的一部分解压到文件 2,然后将解压后的文件 2 提供给用户下载——完全在浏览器端(没有 Node.js 等)。

解压我有:

let fb;

const decB = document.querySelector('button[id="dec"]')
const inputB = document.querySelector('input[type="file"]')
    
input.addEventListener('change', function(e) {
    

    const r = new FileReader()
    r.onload = function () {
        const archive = new Uint8Array(r.result, start, length)
        try {
            fb = pako.inflate(archive);
         
          } catch (err) {
            console.log(err);
          }
    }
    r.readAsArrayBuffer(input.files[0])
}, false)

decB.addEventListener("click", function(e) {
  try {
    const t = new TextDecoder().decode(fb)
    console.log(t)
    
  } catch(err) {
    console.log(err)
  }
}, false)

我希望能够在其他函数中访问 result 的内容。使用全局变量是最好的方法,还是有更合适的解决方案?

这是一个无依赖的小变体

function decompressBlob(blob) {
  const ds = new DecompressionStream('gzip');
  const decompressedStream = blob.stream().pipeThrough(ds);
  return new Response(decompressedStream).blob();
}

function compressBlob(blob) {
  const ds = new CompressionStream('gzip');
  const decompressedStream = blob.stream().pipeThrough(ds);
  return new Response(decompressedStream).blob();
}

const file = new File(['abc'.repeat(100)], 'filename.txt')

console.log('original file size', file.size)

compressBlob(file).then(async newBlob => {
  console.log('compressed blob size:', newBlob.size)
  
  const decompressedBlob = await decompressBlob(newBlob)
  const content1 = await decompressedBlob.text()
  const content2 = await file.text()
  const expected = 'abc'.repeat(100)

  console.log('same content:', content1 === expected)
  console.log('same content:', content2 === expected)
})

然后,如果您想下载它,请创建一个对象 url 并将其附加到具有下载属性的 link

a = document.createElement('a')
a.href = Object.createObjectURL(blob)
a.download = originalFile.name + '.gz'
a.click()

我想如果你想避免回调并且没有一个巨大的代码块,那么你可以尝试使用 async/await 而不是在 blob 本身上使用新的基于承诺的读取方法(https://developer.mozilla.org/en-US/docs/Web/API/Blob/arrayBuffer)

input.addEventListener('change', async evt => {
  const [file] = input.files
  if (file) {
    const arrayBuffer = await file.slice(28, 7412).arrayBuffer()
    const compressed = new Uint8Array(arrayBuffer)
    fileBuffer = pako.inflate(compressed)
    document.getElementById('Decompress').disabled = false
  } else {
    // input was cleared
  }
})