如何迭代大型输入文件?

2024-04-17

我正在尝试访问通过输入字段上传的文件内容的迭代器。

我可以通过 web-sys 将 JS 文件传递​​到 Wasm 中,但是我一生都无法弄清楚如何访问 Rust 中传递的文件的长度和名称之外的任何内容。

我想我可以将整个文件作为 ByteArray 传递到 Wasm 中并对其进行迭代,但最好我想直接迭代文件内容而不进行复制,因为文件本身会很大(~1 GB)。

我在 Mozilla JS 文档中发现我应该能够访问底层文件 blob,通过以下方式从中获取 ReadableStream.stream()方法并从中获取应该能够迭代的 Reader。但在 web-sys 中,.getReader()ReadableStream 的方法返回一个简单的 JSValue,我无法用它做任何有用的事情。

我是否在这里遗漏了一些东西,或者这个功能只是在网络系统中丢失了,还是有其他方法可以做到这一点? 也许在 JS 中创建迭代器并将其传递给 Rust?


我设法使用以下方法获得了一个工作示例读取为二进制字符串 https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.FileReader.html#method.read_as_binary_string.

这是代码

lib.rs

use js_sys::JsString;
use std::cell::RefCell;
use std::rc::Rc;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use web_sys::{console, Event, FileReader, HtmlInputElement};

#[wasm_bindgen(start)]
pub fn main_wasm() {
    let my_file: Rc<RefCell<Vec<u8>>> = Rc::new(RefCell::new(Vec::new()));
    set_file_reader(&my_file);
}

fn set_file_reader(file: &Rc<RefCell<Vec<u8>>>) {
    let filereader = FileReader::new().unwrap().dyn_into::<FileReader>().unwrap();
    let my_file = Rc::clone(&file);

    let onload = Closure::wrap(Box::new(move |event: Event| {
        let element = event.target().unwrap().dyn_into::<FileReader>().unwrap();
        let data = element.result().unwrap();
        let file_string: JsString = data.dyn_into::<JsString>().unwrap();
        let file_vec: Vec<u8> = file_string.iter().map(|x| x as u8).collect();
        *my_file.borrow_mut() = file_vec;
        console::log_1(&format!("file loaded: {:?}", file_string).into());
    }) as Box<dyn FnMut(_)>);

    filereader.set_onloadend(Some(onload.as_ref().unchecked_ref()));
    onload.forget();

    let fileinput: HtmlInputElement = web_sys::window()
        .unwrap()
        .document()
        .expect("should have a document.")
        .create_element("input")
        .unwrap()
        .dyn_into::<HtmlInputElement>()
        .unwrap();

    fileinput.set_id("file-upload");
    fileinput.set_type("file");

    web_sys::window()
        .unwrap()
        .document()
        .unwrap()
        .body()
        .expect("document should have a body")
        .append_child(&fileinput)
        .unwrap();

    let callback = 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).expect("should have a file handle.");
        filereader.read_as_binary_string(&_file).unwrap();
    }) as Box<dyn FnMut(_)>);

    fileinput
        .add_event_listener_with_callback("change", callback.as_ref().unchecked_ref())
        .unwrap();
    callback.forget();
}

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
  </head>
  <body>
    <noscript
      >This page contains webassembly and javascript content, please enable
      javascript in your browser.</noscript
    >
    <script src="./stack.js"></script>
    <script>
      wasm_bindgen("./stack_bg.wasm");
    </script>
  </body>
</html>

and the Cargo.toml

[package]
name = "stack"
version = "0.1.0"
authors = [""]
edition = "2018"


[lib]
crate-type = ["cdylib", "rlib"]

[dependencies]
js-sys = "0.3.55"

wee_alloc = { version = "0.4.2", optional = true }


[dependencies.web-sys]
version = "0.3.4"
features = [
  'Document',
  'Window',
  'console',
  'Event',
  'FileReader',
  'File',
  'FileList',
  'HtmlInputElement']

[dev-dependencies]
wasm-bindgen-test = "0.2"

[dependencies.wasm-bindgen]
version = "0.2.70"

[profile.release]
# Tell `rustc` to optimize for small code size.
opt-level = "s"
debug = false


您可以检查此处的示例:http://rustwasmfileinput.glitch.me/ http://rustwasmfileinput.glitch.me/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何迭代大型输入文件? 的相关文章

随机推荐

  • 检查 python 调试器中的复杂变量,例如 pudb

    如何使用 python 调试器检查复杂变量 列表 字典 对象 值 我是 python 新手 我尝试了 pudb 看起来当变量类型为复杂类型时 调试器仅显示变量的类型 而不显示变量的类型价值 是否可以使用 pudb 检查值 或者有其他 pyt
  • 二叉树类型实例化的高度过高

    我正在尝试类型系统 目前正在尝试在类型级别进行反向级别顺序遍历 这些是我正在使用的类型 type LEFT 0 type VALUE 1 type RIGHT 2 type List ReadonlyArray
  • django.core 序列化器和 Django Rest Framework 序列化器之间的区别

    我现在正在学习 Django 刚刚听说 Django Rest Framework DRF 我想知道 django core 序列化器和 rest framework 序列化器之间有什么区别 是的 我知道 DRF 用于 API django
  • ContentCachingResponseWrapper 生成空响应

    我正在尝试实现过滤器来记录请求和响应Spring MVC应用 我使用以下代码 Component public class LoggingFilter extends OncePerRequestFilter private static
  • 如何在 Three.js 中从三角面获取多边形?

    我在网上查了一下是否有人遇到同样的问题 我正在使用 Three js 我有一个 3DObject 其中可能包含孔 面是三角形的 假设我想从上面看到它 我的目标是获得一个代表顶面周长的多边形 这对我来说意味着不再有三角面 而只有 1 个多边形
  • 在 PHP 中,如何判断 pg_query() 是否是返回数据的查询?

    那么一次成功的mysqli query 如果没有数据则返回 true 并且返回一个mysqli result对象如果有数据 即查询是SELECT SHOW DESCRIBE or EXPLAIN 但随着成功的pg query 无论是否有任何
  • 如何将样式应用于列表中的相邻元素

    我可以只使用 CSS 来完成这个场景吗 我有一个任意长度的元素的无序列表 这些元素排列成一个由四个元素组成的网格 当用户将鼠标悬停在某个元素上时 一些附加内容将在该元素下方下拉 并将其下方的行向下推 Content is here
  • 如何将 CSS 翻译添加到现有翻译中?

    我使用 CSS 翻译将 DIV 元素放置在屏幕上 这工作得很好 除了当稍后位移相同的元素时 原始位移被丢弃 使用 javascript 设置 CSS 起始位置 div style transform translate 800px 400p
  • 监控我的应用程序在 Android 中占用的内存

    我正在尝试优化我的应用程序消耗的内存量 当我的应用程序加载时 按住 home 键 然后选择任务管理器 我可以看到该应用程序占用了 17MB 但该值不会刷新 我如何实时跟踪该值 DDMS 有这个选项吗 请具体说明我已经搜索了很多但没有找到 提
  • 如何使用 start 和 endAngle 渲染 svg 圆

    我使用 start 和 endAngle 渲染了 svg 圆 效果很好 但是当我渲染完整的圆 startAngle为70 endAngle为70 时 输出有很大的不同 0 90 180 270除外 我为这段代码做错了什么 function
  • 如何从 Kubernetes Pod 连接到私有 IP

    我正在尝试从 Pod 内连接到私有 IP 从 Pod 对该 IP 执行 Ping 操作返回无法访问 但是 我可以从主机系统 ping 该 IP 将流量从 pod 路由到目标私有 IP 的最佳方式是什么 Pod 不允许直接连接到 kubern
  • AVAudioPlayer 在调试模式下抛出断点

    每次我加载应用程序时 它都会停止 就像我在此行设置了断点一样 self audioPlayer AVAudioPlayer alloc initWithData dataPersister loadData self fileName er
  • 如何从 Java 系统设置中获取代理设置

    我正在寻找如何在 Windows 下使用 Java 获取系统代理信息的方法 但我只找到了一种方法 但这对我不起作用 public static void main String args throws Throwable System se
  • 红宝石数组内部结构

    ruby 数组内部是如何实现的 主要是在 CRuby 中 但欢迎任何其他信息 它们是像 C 向量一样可增长的数组还是基于列表的 移位 取消移位以及通过索引访问元素的复杂性是多少 它们是可增长的数组 在最后增长 shift is O 1 un
  • hive中每行的百分比计算

    我在配置单元中有一个具有以下架构的表 差值 int 计数值 int 值为 5 2 30 1 90 1 100 1 现在我想找到每个 count value 与 count value 总和的百分比 每行的值类似于 count value s
  • 终止设备上的调试

    我对设备上的调试有点困惑 当我使用模拟器时 在调试会话之后 我只需关闭模拟器窗口 但是在我的设备上调试时 如何关闭会话 只需断开 USB 电缆即可 并且安装的 apk 由Eclipse安装 应该手动删除 您可以通过转到 调试 视角 右键单击
  • 当 readdir() 返回文件名时,stat() 错误“没有这样的文件或目录”

    我无法识别 stat 引发的错误 下面的程序读取目录中的所有文件并打印文件名 DIR dp struct dirent dirp struct stat sb if dp opendir argv 1 NULL perror can t o
  • WPF - MVVM - 组合框选定项

    I have ViewModel 实施的INotifyPropertyChanged 在后台和类中Category它只有一个 type 属性string 我的 ComboBox SelectedItem 绑定到类别的实例 当我更改实例的值时
  • 如何更改导航视图中的分隔符颜色?

    我正在尝试使用 NavigationView 来实现 NavigationDrawer 我通过在菜单中设置组 ID 添加了分隔符 但是我看不到分隔符 我想这是因为分隔符颜色与背景相同 所以我想改变分隔符的颜色 但我找不到办法改变它 谁能帮我
  • 如何迭代大型输入文件?

    我正在尝试访问通过输入字段上传的文件内容的迭代器 我可以通过 web sys 将 JS 文件传递 到 Wasm 中 但是我一生都无法弄清楚如何访问 Rust 中传递的文件的长度和名称之外的任何内容 我想我可以将整个文件作为 ByteArra