如何在浏览器中处理webassembly中的大文件?



我现在有一个应用程序(c++),它根据格式规范验证文件。要验证的文件可能非常大(通常为200 MB到2 GB,但我也见过高达50 GB的文件)。对于文件访问,我现在使用内存映射文件,因为它很容易&快。

我现在希望能够将其部署为一个网页,用户可以将他们的文件放到&然后它将被验证。由于文件大小,上传它没有意义,所以我在考虑直接在浏览器中验证它。

由于代码库也用于命令行应用程序&作为本地应用程序的库,我在考虑验证的webassembly变体。

是否有一个有效的方法使用webassembly在浏览器中做验证?到目前为止,我发现的唯一一件事就是将其加载到JS-Array中,然后使其可用于c++ -但这非常慢。大小有限(至少我做的方式有限)。对于这样的用例,推荐的方法是什么?

这不是一个完整的答案,因为我也在寻找一个可行的解决方案。但我将分享目前为止我所知道的。

下面是一个存储库,演示了如何使用Rust和wasm-bindgen读取文件的第一个字节。考虑到我已经尝试了1GB的文件,并且几乎立即得到了结果,我认为它不会将整个文件上传到浏览器。

而且,我敢肯定你现在已经听说过Origin私有文件系统支持的浏览器中的SQLite Wasm了。因为SQLite是用c++编写的,所以这一点应该更加重要。

从我(有限)的理解,一旦你有一个FileHandle(无论是从OPFS, FileInput,或其他)其余的是相同的。因此,无论你是拖放,使用文件上传还是从OPFS读取(我的目标),上述解决方案都应该有效。

实际上,在示例repo中,文件句柄被传递给一个worker(它通过fileHandle.createSyncAccessHandle具有同步访问)

document.getElementById("file_picker").addEventListener(
"change",
function() {
let file = this.files[0];
myWorker.postMessage({ file: file, offset: BigInt(0) });

工作线程正在使用句柄

onmessage = async function(e) {
let workerResult = read_at_offset_sync(
e.data.file,
e.data.offset,
);
postMessage(workerResult);
};

read_at_offset_sync是Rust中使用web_sys crate/bridge读取文件的函数。我的另一个假设是,emscripten也提供了类似的功能。

最后,如果你有办法处理FileSystemSyncAccessHandle,它将为你提供一个read()方法,该方法可以直接读取(部分)文件,并带偏移量,到BufferArray中。在Rust中,它与wasm_bindgencrate一起可用。

最新更新