#s3 #random-access #aws #local-filesystem #reader #api-bindings #aws-sdk-s3

s3reader

使用字节偏移量像本地文件一样读取 S3 对象

8 个版本 (4 个稳定版)

1.2.1 2024年5月1日
1.2.0 2024年4月11日
1.1.0 2023年12月24日
1.0.0 2022年10月14日
0.1.0 2022年8月14日

#289 in 文件系统

Download history 93/week @ 2024-04-25 47/week @ 2024-05-02 10/week @ 2024-05-16 10/week @ 2024-05-23 9/week @ 2024-05-30 9/week @ 2024-06-06 28/week @ 2024-06-13 14/week @ 2024-06-20 1/week @ 2024-06-27 4/week @ 2024-07-04 43/week @ 2024-07-11 32/week @ 2024-07-18 83/week @ 2024-07-25 32/week @ 2024-08-01 4/week @ 2024-08-08

每月151次下载
用于 atg

MIT 许可证

25KB
393 代码行

Build crates.io doc-rs

S3Reader

A Rust 库,用于将 S3 对象读取为类似本地文件系统上的文件(几乎)。S3Reader 添加了 ReadSeek 特性,允许将游标放置在 S3 对象的任何位置并从任何字节偏移量读取。这允许对 S3 对象中的字节进行随机访问。

用法

将此添加到您的 Cargo.toml

[dependencies]
s3reader = "1.0.0"

使用 BufRead 按行读取

use std::io::{BufRead, BufReader};

use s3reader::S3Reader;
use s3reader::S3ObjectUri;


fn read_lines_manually() -> std::io::Result<()> {
    let uri = S3ObjectUri::new("s3://my-bucket/path/to/huge/file").unwrap();
    let s3obj = S3Reader::open(uri).unwrap();

    let mut reader = BufReader::new(s3obj);

    let mut line = String::new();
    let len = reader.read_line(&mut line).unwrap();
    println!("The first line >>{line}<< is {len} bytes long");

    let mut line2 = String::new();
    let len = reader.read_line(&mut line2).unwrap();
    println!("The next line >>{line2}<< is {len} bytes long");

    Ok(())
}

fn use_line_iterator() -> std::io::Result<()> {
    let uri = S3ObjectUri::new("s3://my-bucket/path/to/huge/file").unwrap();
    let s3obj = S3Reader::open(uri).unwrap();

    let reader = BufReader::new(s3obj);

    let mut count = 0;
    for line in reader.lines() {
        println!("{}", line.unwrap());
        count += 1;
    }

    Ok(())
}

使用 Seek 跳转到位置

use std::io::{Read, Seek, SeekFrom};

use s3reader::S3Reader;
use s3reader::S3ObjectUri;

fn jump_within_file() -> std::io::Result<()> {
    let uri = S3ObjectUri::new("s3://my-bucket/path/to/huge/file").unwrap();
    let mut reader = S3Reader::open(uri).unwrap();

    let len = reader.len();

    let cursor_1 = reader.seek(SeekFrom::Start(len as u64)).unwrap();
    let cursor_2 = reader.seek(SeekFrom::End(0)).unwrap();
    assert_eq!(cursor_1, cursor_2);

    reader.seek(SeekFrom::Start(10)).unwrap();
    let mut buf = [0; 100];
    let bytes = reader.read(&mut buf).unwrap();
    assert_eq!(buf.len(), 100);
    assert_eq!(bytes, 100);

    Ok(())
}

Q/A

这个库真的提供了对 S3 对象的随机访问吗?
根据这个 StackOverflow 答案,是的。

读取是同步的还是异步的?
S3-SDK 主要使用异步操作,但 ReadSeek 特性需要同步方法。由于这个原因,我使用阻塞的 tokio 运行时来包装异步调用。这可能不是最好的解决方案,但对我来说效果很好。任何改进建议都非常欢迎。

这有什么用?
取决于您的用例。如果您需要访问大文件/S3 对象中间的随机字节,这个库很有用。例如,您可以读取它来流式传输 mp4 文件。它对于一些生物信息学应用也非常有用,您可能有一个巨大的、几个 GB 的参考基因组,但只需要访问几个基因的数据,这仅相当于几个 MB。

依赖项

~24–32MB
~431K SLoC