我正在尝试读取文件,解密文件并返回数据。因为文件可能很大,所以我想在流中执行此操作。
我找不到实现流的好的模式。我正在尝试做这样的事情:
let stream = stream::unfold(decrypted_init_length, |decrypted_length| async move {
if decrypted_length < start + length {
let mut encrypted_chunk = vec![0u8; encrypted_block_size];
match f.read(&mut encrypted_chunk[..]) {
Ok(size) => {
if size > 0 {
let decrypted = my_decrypt_fn(&encrypted_chunk[..]);
let updated_decrypted_length = decrypted_length + decrypted.len();
Some((decrypted, updated_decrypted_length))
} else {
None
}
}
Err(e) => {
println!("Error {}", e);
None
}
}
} else {
None
}
});
问题是上述异步关闭中不允许
f.read
并出现以下错误:89 | | match f.read(&mut encrypted_chunk[..]) {
| | -
| | |
| | move occurs because `f` has type `std::fs::File`, which does not implement the `Copy` trait
| | move occurs due to use in generator
我不想在闭包本身内部打开
f
。有没有更好的方法来解决此问题?我可以使用其他的 crate 或特征或方法(即,不是stream::unfold
)。
最佳答案
我找到了一个解决方案:在here使用async-stream
crate 。stream::unfold
对我不起作用的原因之一是async move
闭包不允许外部访问mut
变量,例如f
文件句柄。
现在使用async-stream
,我将代码更改为以下代码,并且可以正常工作:(请注意此 crate 添加的yield
)。
use async_stream::try_stream;
<snip>
try_stream! {
while decrypted_length < start + length {
match f.read(&mut encrypted_chunk[..]) {
Ok(size) =>
if size > 0 {
println!("read {} bytes", size);
let decrypted = my_decrypt_fn(&encrypted_chunk[..size], ..);
decrypted_length = decrypted_length + decrypted.len();
yield decrypted;
} else {
break
}
Err(e) => {
println!("Error {}", e);
break
}
}
}
}
更新:
我发现
async-stream
有一些限制,我不能忽略。我最终直接实现了Stream
,不再使用async-stream
。现在我的代码如下所示:pub struct DecryptFileStream {
f: File,
<other_fields>,
}
impl Stream for DecryptFileStream {
type Item = io::Result<Vec<u8>>;
fn poll_next(self: Pin<&mut Self>,
_cx: &mut Context<'_>) -> Poll<Option<io::Result<Vec<u8>>>> {
// read the file `f` of self and business_logic
//
if decrypted.len() > 0 {
Poll::Ready(Some(Ok(decrypted)))
} else {
Poll::Ready(None)
}
}
}
//. then use the above stream:
let stream = DecryptFileStream::new(...);
Response::new(Body::wrap_stream(stream))
关于rust - 如何通过读取和转换文件来创建Stream?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60876434/