首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将blob内容读取到现有SharedArrayBuffer中

将blob内容读取到现有SharedArrayBuffer中
EN

Stack Overflow用户
提问于 2017-06-27 04:45:02
回答 1查看 302关注 0票数 0

我正在尝试找到将Blob的内容读取到现有SharedArrayBuffer中的最有效的方法,其起源是等待缓冲区被poplated的工作进程。在我的例子中,我可以保证SharedArrayBuffer至少足够长来容纳Blob的全部内容。我想出的最好的方法是:

代码语言:javascript
复制
// Assume 'blob' is the blob we are reading
// and 'buffer' is the SharedArrayBuffer.
const fr = new FileReader();
fr.addEventListener('load', e =>
  new Uint8Array(buffer).set(new Uint8Array(e.target.result)));
fr.readAsArrayBuffer(blob);

这似乎效率很低,尤其是在读取的blob相对较大的情况下。

EN

回答 1

Stack Overflow用户

发布于 2017-09-23 17:30:00

Blob不是Transferable对象。此外,FileReader上也没有可用的.readAsSharedArrayBuffer方法。

但是,如果您只需要同时读取来自多个工作进程的Blob,我相信您可以使用URL.createObjectURL()fetch来实现这一点,尽管我没有在多个工作进程中进行过测试:

代码语言:javascript
复制
// === main thread ===
let objectUrl = URL.createObjectURL(blob);
worker1.postMessage(objectUrl);
worker2.postMessage(objectUrl);

// === worker 1 & 2 ===
self.onmessage = msg => {
    fetch(msg.data)
        .then(res => res.blob())
        .then(blob => {
            doSomethingWithBlob(blob);
        });
};

否则,据我所知,确实没有一种有效的方法将数据从文件加载到SharedArrayBuffer中。

我还在这里提供了一种方法,用于将blob的块从主线程传输到单个工作线程。就我的用例而言,文件太大,无法将整个内容读取到单个数组缓冲区中(无论是否共享),因此我使用.slice来处理块。这样,您就可以通过使用Transferable ArrayBuffer的多个.postMessage调用,以类似流的方式将大量数据传递给单个工作进程

代码语言:javascript
复制
// === main thread ===
let eof = false;
let nextBuffer = null;
let workerReady = true;

let read = 0;
function nextChunk() {
    let end = read + chunkSize;
    if(end >= file.length) {
        end = file.length;
        eof = true;
    }

    let slice = file.slice(read, end);
    read = end;

    fr.readAsArrayBuffer(slice);
}

fr.onload = event => {
    let ab = event.target.result;

    if(workerReady) {
        worker.postMessage(ab, [ab]);
        workerReady = false;
        if(!eof) nextChunk();
    }
    else {
        nextBuffer = ab;
    }
};

// wait until the worker finished the last chunk
// ... otherwise we'll flood main thread's heap
worker.onmessage = msg => {
    if(nextBuffer) {
        worker.postMessage(nextBuffer, [nextBuffer]);
        nextBuffer = null;
    }
    else if(!eof && msg.ready) {
        nextChunk();
    }
};

nextChunk();


// === worker ===
self.onmessage = msg => {
    let ab = msg.data;
    // ... do stuff with data ...
    self.postMessage({ready:true});
};

这会将数据块读入主线程中的ArrayBuffer,将其传输给worker,然后在等待worker处理前一个块的同时将下一个块读入内存。这基本上确保了两个线程始终处于忙碌状态。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44768386

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档