我现在正在使用WebAssembly,希望能够将文件的字节从JavaScript传递到Rust代码。目前,我已经将以下Rust结构暴露给JavaScript:
use js_sys::{Function, Uint8Array};
use wasm_bindgen::prelude::{wasm_bindgen, JsValue};
#[wasm_bindgen]
pub struct WasmMemBuffer {
buffer: Vec<u8>,
}
#[wasm_bindgen]
impl WasmMemBuffer {
#[wasm_bindgen(constructor)]
pub fn new(byte_length: u32, f: &Function) -> Self {
let mut buffer = vec![0; byte_length as usize];
unsafe {
let array = Uint8Array::view(&mut buffer);
f.call1(&JsValue::NULL, &JsValue::from(array))
.expect("The callback function should not throw");
}
Self { buffer }
}
}
这个结构体WasmMemBuffer
将指向WebAssembly内存中的一个位置,这意味着我可以从JavaScript向它写入内容,而无需任何代价高昂的复制操作。
import { WasmMemBuffer } from 'rust-crate';
const buf = new WasmMemBuffer(1000, (arr: Uint8Array) => {
for (let i = 0; i < arr.length; i++) {
arr[i] = 1.0; // Initialize the buffer with ones
}
});
但是,我希望将用户提交的文件内容 * 直接 * 读入WebAssembly的线性内存,而无需创建ArrayBuffer
,将其转换为Uint8Array
,并将其值复制到WasmMemBuffer
。FileReader
在调用readAsArrayBuffer
时分配了一个新的ArrayBuffer
。我想将它指向WasmMemBuffer
。有什么方法可以做到这一点吗?以下是我用来读取文件的代码,以供参考。
// e is the onchange event from a <input type="file"> element
function readFile(e: Event) {
const target = e?.target as HTMLInputElement;
const file = target?.files?.[0];
if (!target || !file) {
return;
}
const reader = new FileReader();
reader.onload = (e) => {
const res = e.target?.result as ArrayBuffer;
if (res) {
// Do something with res
}
};
reader.readAsArrayBuffer(file);
}
1条答案
按热度按时间pxyaymoc1#
忘记了这个问题,但我通过使用分块的
FileReader
Package 器解决了这个问题,这也有一个令人愉快的效果,即允许以一种更有效的方式读取非常大的文件。下面是课程: