本文介绍了如何使用 Rust 将带有 JavaScript 的文件读取到 WebAssembly?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何传递 File 以在 WebAssembly 内存上下文中读取?

How can I pass a File to be read within the WebAssembly memory context?

使用 JavaScript 在浏览器中读取文件很容易:

Reading a file in the browser with JavaScript is easy:

<input class="file-selector" type="file" id="files" name="files[]" />

我能够使用 crate stdweb 引导用 Rust 编写的 WebAssembly 代码,添加一个事件监听器到DOM 元素并启动一个 FileReader:

I was able to bootstrap WebAssembly code written in Rust with the crate stdweb, add an event listener to the DOM element and fire up a FileReader:

let reader = FileReader::new();
let file_input_element: InputElement = document().query_selector(".file-selector").unwrap().unwrap().try_into().unwrap();
file_input_element.add_event_listener(enclose!( (reader, file_input_element) move |event: InputEvent| {
    // mystery part
}));

在 JavaScript 中,我会从元素中获取文件并将其传递给阅读器,但是,stdweb 的 API 需要以下签名:

In JavaScript, I would get the file from the element and pass it to the reader, however, the API of stdweb needs the following signature:

pub fn read_as_array_buffer<T: IBlob>(&self, blob: &T) -> Result<(), TODO>

我不知道如何实现 IBlob,而且我确信无论是使用 stdweb API 还是我对 WebAssembly/Rust 的理解,我都遗漏了一些明显的东西.我希望有比 更简洁的东西将内容转换为 UTF-8.

I have no idea how to implement IBlob and I am sure that I am missing something obvious either with the stdweb API or in my understanding of WebAssembly/Rust. I was hoping that there is something less verbose than converting stuff to UTF-8.

推荐答案

它在 FileReader 本身从 JavaScript 传递到 WebAssembly 时起作用.这似乎也是一种干净的方法,因为无论如何都必须通过 JavaScript API 读取数据 - 无需从 WASM 调用 JS.

It works when the FileReader itself is passed from JavaScript to WebAssembly. It also seems like a clean approach because the data has to be read by the JavaScript API anyway - no need to call JS from WASM.

index.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Read to wasm</title>
</head>
<body>
<input type="file" id="file-input"/>
<script src="reader.js"></script>
<script>
    var fileReader = new FileReader();
    fileReader.onloadend = e => Rust.reader
            .then(reader=> {
                window.alert(reader.print_result(fileReader));
            });

    var fileInputElement = document.getElementById("file-input");
    fileInputElement.addEventListener("change", e => fileReader.readAsText(fileInputElement.files[0]));
</script>
</body>
</html>

ma​​in.rs

#![feature(proc_macro)]

#[macro_use]
extern crate stdweb;

use stdweb::js_export;
use stdweb::web::FileReader;
use stdweb::web::FileReaderResult;

#[js_export]
fn print_result(file_reader: FileReader) -> String {
    match file_reader.result() {
        Some(value) => match value {
            FileReaderResult::String(value) => value,
            _ => String::from("not a text"),
        }
        None => String::from("empty")
    }
}

fn main() {
    stdweb::initialize();

    stdweb::event_loop();
}

这篇关于如何使用 Rust 将带有 JavaScript 的文件读取到 WebAssembly?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-29 07:37