如何统计流文件字节数?rust-s3实现及流计数方法咨询
解决方案
1. rust-s3 put_object_stream 本身的限制
rust-s3 的 put_object_stream 方法不会直接返回上传的字节数——因为 AWS S3 的 PutObject API 响应默认不包含该统计值,该方法的返回值仅包含请求的元数据(如 ETag、对象版本 ID 等)。
2. 自定义流包装器统计字节数
你可以通过包装原始流,在数据传输过程中实时统计读取的字节数。以下是基于 Tokio AsyncRead trait 的实现示例:
定义字节计数器包装器
use tokio::io::{AsyncRead, ReadBuf}; use std::pin::Pin; use std::task::{Context, Poll}; // 包装 AsyncRead 流,统计读取的字节数 struct ByteCounter<R> { inner: R, count: u64, } impl<R> ByteCounter<R> { // 创建新的计数器包装流 fn new(inner: R) -> Self { ByteCounter { inner, count: 0 } } // 获取已统计的字节数 fn get_count(&self) -> u64 { self.count } } // 为 ByteCounter 实现 AsyncRead impl<R: AsyncRead + Unpin> AsyncRead for ByteCounter<R> { fn poll_read( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<std::io::Result<()>> { let filled_before = buf.filled().len(); // 委托给内部流的读取逻辑 let result = Pin::new(&mut self.inner).poll_read(cx, buf); let filled_after = buf.filled().len(); // 累加本次读取的字节数 self.count += (filled_after - filled_before) as u64; result } }
使用包装流上传并统计字节数
// 用 ByteCounter 包装你的原始流 let mut counted_stream = ByteCounter::new(your_stream); // 执行 S3 上传操作 bucket.put_object_stream(&mut counted_stream, filename).await?; // 获取最终上传的字节数 let total_bytes = counted_stream.get_count(); println!("成功上传 {} 字节", total_bytes);
注意事项
- 如果上传过程中发生错误,
get_count()返回的是已成功传输的字节数,你可以根据业务需求处理这种部分上传的情况。 - 该实现基于 Tokio 的异步 IO 模型,与 rust-s3 的异步 API 完全兼容。
内容的提问来源于stack exchange,提问作者Fred Hors
相关产品推荐
相关产品推荐

