【问题标题】:How do I asynchronously calculate the checksum of a file on the hard disk in Rust?如何在 Rust 中异步计算硬盘上文件的校验和?
【发布时间】:2018-11-21 13:17:12
【问题描述】:

我在 Rust / Tokio 堆栈中有一个 TCP 文件服务器。

当客户端上传文件时,数据将从tokio::net::TcpStream 读取并写入futures_fs::FsWriteSink,该futures_fs::FsWriteSink 已在单独的futures_fs::FsPool 上启动。

文件完全上传后,我需要通过与客户端发送的校验和检查其一致性。

异步计算校验和的最简单方法是什么,尤其是在文件不适合 RAM 的情况下?

【问题讨论】:

  • 使用BufReader?
  • 您可能还想探索在上传时计算实际上传数据的校验和。此时您已经有数据通过您的处理,因此计算校验和几乎是一项免费操作。如果您有性能方面的考虑,则尤其如此,因为通过在将数据保存到磁盘后计算数据的校验和,您实际上将支持文件上传所需执行的 IO 操作加倍。
  • 是的,我完全同意。但似乎我需要自己实现这样的事情,不是吗?我想要另一个Sink 之类的东西,我可以在其中提供块,以便Sink 可以即时计算校验和。
  • 什么校验和?校验和的实现自然是异步的吗?如果是这样,只需使用它。如果不是,那么这是 What is the best approach to encapsulate blocking I/O in future-rs? 的副本。

标签: file asynchronous rust checksum rust-tokio


【解决方案1】:

这取决于您要使用的校验和算法,但以md5 crate 为例,您可以即时计算校验和。应该这样做:

// When starting the file transfer
let mut md5_context = md5::Context::new();

// ...

// as part of your existing processing for each block of data
md5_context.consume (&block);

// ...

// once the last block has been processed
return md5_context.compute();

【讨论】:

  • 这似乎是完全同步的。 OP 已明确请求异步解决方案。
  • @Shepmaster 我不知道你怎么知道这是同步的还是异步的:我只是说对于每个数据块他应该调用md5_context.consume,我从来没有说过他应该这样做在同步循环中。
【解决方案2】:

实际上,在这种情况下,使简单的哈希算法异步有些多余,只要一次 MD5 计算花费的时间少于 1 us(大约 500 ns)。

但是,tokio 现在提供了一个新的blocking API。它允许使用内部线程机制执行阻塞或 CPU 繁重的操作。

【讨论】:

    猜你喜欢
    • 2017-04-21
    • 1970-01-01
    • 1970-01-01
    • 2022-12-03
    • 2012-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多