Rust 有没有办法实现ZipFile的Send特性?

Rust 有没有办法实现ZipFile的Send特性?,rust,zip,Rust,Zip,我想使用另一个线程读取.zip文件 但编译器向我显示了以下错误: error[E0277]:未满足特性绑定'std::io::Read:std::marker::Send' -->src/main.rs:10:24 | 10 |让读取器|线程=线程::生成(移动| |{ |^^^^^^^^^^^`std::io::Read`无法在线程之间安全发送 | =help:trait`std::marker::Send`未为`std::io::Read'实现` =注意:由于“`std::marker::S

我想使用另一个线程读取
.zip
文件

但编译器向我显示了以下错误:

error[E0277]:未满足特性绑定'std::io::Read:std::marker::Send'
-->src/main.rs:10:24
|
10 |让读取器|线程=线程::生成(移动| |{
|^^^^^^^^^^^`std::io::Read`无法在线程之间安全发送
|
=help:trait`std::marker::Send`未为`std::io::Read'实现`
=注意:由于“`std::marker::Send`for`&mut std::io::Read”的impl上的要求,因此必需`
=注意:必需,因为它出现在类型“std::io::Take”中`
=注意:必需,因为它出现在'zip::crc32::Crc32Reader'类型中`
=注意:必需,因为它出现在类型'zip::read::ZipFileReader'中`

=注意:必需,因为它出现在类型中`[closure@src/main.rs:10:38:13:6文件:zip::read::ZipFile这是
zip
板条箱API的限制,您不能真正更改任何内容。问题是,文件
ZipArchive
是通过调用
new
并传递读取器创建的,读取器实现了
read
Seek
。但这些是对读卡器的唯一要求(特别是,读卡器不需要是
克隆的
)。因此,整个
ZipArchive
只能拥有一个读卡器

但是现在
ZipArchive
能够生成
ZipFile
s,这些文件本身实现了
Read
。如果整个
ZipArchive
只有一个读卡器,那该如何工作呢?通过共享!唯一的读卡器在存档和所有文件之间共享。但是这种共享不是线程保存!对读取的可变引用er存储在每个
ZipFile
——这违反了Rust的核心原则

这是板条箱的已知问题,正在讨论中


那么您现在可以做什么呢?不是很多,但是有一些可能性(正如库作者所提到的)可能适合您的用例:

  • 您可以先将整个文件解压缩到内存中,然后将原始数据发送到另一个线程对其进行计算。类似于:

    let data = Vec::new();
    BufReader::new(file).read_to_end(&mut data)?;
    let reader_thread= thread::spawn(move || {
        // Do stuff with `data`
    });
    
    但是,如果您只想对所有文件计算一个廉价的哈希函数,那么将内容加载到内存中可能比动态计算哈希要慢,并且如果您的文件很大,则可能不可行

  • 为每个线程创建一个
    ZipArchive
    。如果存档中有许多小文件,这可能会非常慢


一个小提示:启动线程需要花费时间。您通常不希望为每个工作单元启动一个线程,而是希望在线程池中维护固定数量的线程,管理队列中的工作,并将工作分配给空闲的工作线程。这可能会满足您的需要

let data = Vec::new();
BufReader::new(file).read_to_end(&mut data)?;
let reader_thread= thread::spawn(move || {
    // Do stuff with `data`
});