Eri*_*lze 5 rust webassembly wasm-bindgen
我正在尝试访问通过输入字段上传的文件内容的迭代器。
我可以通过 web-sys 将 JS 文件传递到 Wasm 中,但我一生都无法弄清楚如何访问 Rust 中传递的文件的长度和名称之外的任何内容。
我想我可以将整个文件作为 ByteArray 传递到 Wasm 中并对其进行迭代,但最好我想直接迭代文件内容而不进行复制,因为文件本身会很大(~1 GB)。
我在 Mozilla JS 文档中发现,我应该能够访问底层文件 blob,通过该.stream()方法从中获取 ReadableStream,并从中获取应该能够迭代的 Reader。但在 web-sys 中,.getReader()ReadableStream 的方法返回一个简单的 JSValue,我无法用它做任何有用的事情。
我是否在这里遗漏了一些东西,或者这个功能只是在网络系统中丢失了,还是有其他方法可以做到这一点?也许在 JS 中创建迭代器并将其传递给 Rust?
我认为你可以使用 做类似的事情FileReader。
这是一个示例,我在其中记录文件的文本内容:
use wasm_bindgen::prelude::*;
use web_sys::{Event, FileReader, HtmlInputElement};
use wasm_bindgen::JsCast;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}
#[wasm_bindgen(start)]
pub fn main() -> Result<(), JsValue> {
let window = web_sys::window().expect("no global `window` exists");
let document = window.document().expect("should have a document on window");
let body = document.body().expect("document should have a body");
let filereader = FileReader::new().unwrap().dyn_into::<FileReader>()?;
let closure = Closure::wrap(Box::new(move |event: Event| {
let element = event.target().unwrap().dyn_into::<FileReader>().unwrap();
let data = element.result().unwrap();
let js_data = js_sys::Uint8Array::from(data);
let rust_str: String = js_data.to_string().into();
log(rust_str.as_str());
}) as Box<dyn FnMut(_)>);
filereader.set_onloadend(Some(closure.as_ref().unchecked_ref()));
closure.forget();
let fileinput: HtmlInputElement = document.create_element("input").unwrap().dyn_into::<HtmlInputElement>()?;
fileinput.set_type("file");
let closure = Closure::wrap(Box::new(move |event: Event| {
let element = event.target().unwrap().dyn_into::<HtmlInputElement>().unwrap();
let filelist = element.files().unwrap();
let file = filelist.get(0).unwrap();
filereader.read_as_text(&file).unwrap();
//log(filelist.length().to_string().as_str());
}) as Box<dyn FnMut(_)>);
fileinput.add_event_listener_with_callback("change", closure.as_ref().unchecked_ref())?;
closure.forget();
body.append_child(&fileinput)?;
Ok(())
}
Run Code Online (Sandbox Code Playgroud)
和 HTML:
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
</head>
<body>
<script type="module">
import init from './pkg/without_a_bundler.js';
async function run() {
await init();
}
run();
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
和Cargo.toml
[package]
name = "without-a-bundler"
version = "0.1.0"
authors = [""]
edition = "2018"
[lib]
crate-type = ["cdylib"]
[dependencies]
js-sys = "0.3.51"
wasm-bindgen = "0.2.74"
[dependencies.web-sys]
version = "0.3.4"
features = [
'Blob',
'BlobEvent',
'Document',
'Element',
'Event',
'File',
'FileList',
'FileReader',
'HtmlElement',
'HtmlInputElement',
'Node',
'ReadableStream',
'Window',
]
Run Code Online (Sandbox Code Playgroud)
但是我不知道如何使用get_reader()of ReadableStream,因为根据链接的文档,它应该返回 aReadableStreamDefaultReader或 a ReadableStreamBYOBReader。虽然后者是实验性的,因此我认为这是可以理解的,但它不存在于 中web-sys,我不知道为什么ReadableStreamDefaultReader也不存在。
| 归档时间: |
|
| 查看次数: |
2518 次 |
| 最近记录: |