javascript - 合并大量 UInt8Array

标签 javascript arrays concatenation ipfs typed-arrays

我这里有一些代码,例如,在浏览器中使用 js-ipfs 下载 Arch Linux 。目前正在运行。

async function start(event) {

  console.log("Starting IPFS...");
  node = await Ipfs.create();

  for await (const file of node.get('QmQxBX5ZKRY8k6W2UqYTMxhdFTvkmNw8X7GJN3t5UiyBpe')) {
    console.log("Starting");
    var content = [];
    for await (const chunk of file.content) {
      console.log("Gathering");
      content = mergeTypedArrays(content, chunk); // slow
    }
    console.log("Assembling");
    saveFile("arch.iso", "application/octet-stream", content);
    console.log("Done");
  };
}

// https://stackoverflow.com/a/35633935/2700296
function mergeTypedArrays(a, b) {
  // Checks for truthy values on both arrays
  if(!a && !b) throw 'Please specify valid arguments for parameters a and b.';  

  // Checks for truthy values or empty arrays on each argument
  // to avoid the unnecessary construction of a new array and
  // the type comparison
  if(!b || b.length === 0) return a;
  if(!a || a.length === 0) return b;

  // Make sure that both typed arrays are of the same type
  if(Object.prototype.toString.call(a) !== Object.prototype.toString.call(b))
      throw 'The types of the two arguments passed for parameters a and b do not match.';

  var c = new a.constructor(a.length + b.length);
  c.set(a);
  c.set(b, a.length);

  return c;
}

// https://stackoverflow.com/a/36899900/2700296
function saveFile (name, type, data) {
  if (data !== null && navigator.msSaveBlob) {
    return navigator.msSaveBlob(new Blob([data], { type: type }), name);
  }
  var a = document.createElement('a');
  a.style.display = "none";
  var url = window.URL.createObjectURL(new Blob([data], {type: type}));
  a.setAttribute("href", url);
  a.setAttribute("download", name);
  document.body.appendChild(a);
  a.click();
  window.URL.revokeObjectURL(url);
  a.remove();
}

问题是,当前组装 UInt8Array 发送到 saveFile 的方法涉及在下载的所有约 2600 个 block 上重新创建一个新的 UInt8Array,这确实很慢且效率低下。我尝试将所有这些 block 插入一个数组,然后将其组合,但我不知道如何获取约 2600 个 UInt8Array 的数组并将它们压平为一个 UInt8Array。有人可以给我一些建议吗?

最佳答案

想太多了。最终直接从 UInt8Array 数组创建了一个 blob。

async function start(event) {

  console.log("Starting IPFS...");
  node = await Ipfs.create();

  for await (const file of node.get('QmQxBX5ZKRY8k6W2UqYTMxhdFTvkmNw8X7GJN3t5UiyBpe')) {
    console.log("Starting");
    var content = [];
    for await (const chunk of file.content) {
      console.log("Gathering");
      content.push(chunk);
    }
    console.log("Assembling");
    saveFile(content, "archlinux-2020.04.01-x86_64.iso");
    console.log("Done");
  };

}

// https://stackoverflow.com/a/36899900/2700296
function saveFile(data, fileName) {
  if (data !== null && navigator.msSaveBlob) {
    return navigator.msSaveBlob(new Blob(data, { "type": "application/octet-stream" }), fileName);
  }
  var a = document.createElement('a');
  a.style.display = "none";
  var url = window.URL.createObjectURL(new Blob(data, {type: "application/octet-stream"}));
  a.setAttribute("href", url);
  a.setAttribute("download", fileName);
  document.body.appendChild(a);
  a.click();
  window.URL.revokeObjectURL(url);
  a.remove();
}

关于javascript - 合并大量 UInt8Array,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61332837/

相关文章:

javascript - 将 Promise 与事件发射器一起使用

javascript - ToggleClass 使用 jQuery 制作动画?

arrays - Swift 错误 - 无法将类型 'MKOverlay' 的值转换为预期的参数类型 '@noescape (MKOverlay) throws -> Bool' - 执行 indexOf 时

c - 另一个结构中的结构数组

使用 concat 更新 MySQL 不起作用

shell - 如何使用 Hadoop FS shell 将 hadoop 中的两个文件连接成一个文件?

javascript - Moment.js 以本地格式显示小时

javascript - 为什么触发mouseleave

java - 嵌套 For 循环终止后递增

mysql - SQL如何使用相同的字段具有不同的连接条件?