合并大量 UInt8Arrays
Merging Large Number of UInt8Arrays
我这里有一些代码,例如,使用 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");
};
}
//
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;
}
//
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 个下载的块上重新创建一个新的 UInt8Array,这确实很慢且效率低下。我已经尝试将所有这些块推送到一个数组,然后将其组合,但我无法弄清楚如何获取 ~2600 UInt8Arrays 的数组并将它们展平为一个 UInt8Array。有人对我有什么建议吗?
是想多了。刚刚结束直接从 UInt8Array
s.
的数组创建一个 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");
};
}
//
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();
}
我这里有一些代码,例如,使用 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");
};
}
//
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;
}
//
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 个下载的块上重新创建一个新的 UInt8Array,这确实很慢且效率低下。我已经尝试将所有这些块推送到一个数组,然后将其组合,但我无法弄清楚如何获取 ~2600 UInt8Arrays 的数组并将它们展平为一个 UInt8Array。有人对我有什么建议吗?
是想多了。刚刚结束直接从 UInt8Array
s.
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");
};
}
//
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();
}