rust - 写入带有偏移量的静态大小文件

标签 rust

我正在尝试在下载文件的随机 block 并将它们就地组装的上下文中通过随机访问将字节写入文件。 std::io::Write 似乎仅限于顺序写入,因此我当前使用以下实现,它首先需要下载所有 block ,然后执行大操作 write_all一旦所有 block 都在内存中。

use rand::prelude::*;
use rand; // 0.7.3

fn download<W: std::io::Write>(writer: &mut W) -> std::io::Result<()>
{
    // the size (20) is known
    let mut buf = [0u8; 20];
    
    // simulate downloading four 5 byte chunks at random disjoint slices in *buf*
    for n in (0..20).step_by(5).collect::<Vec<usize>>().choose_multiple(&mut thread_rng(), 4) {
        let n = *n as usize;
        let chunk: [u8; 5] = rand::random();
        buf[n..n+5].clone_from_slice(&chunk);
    }
    
    println!("filled buffer: {:?}", buf);
    
    // finally, do (unbuffered) write
    writer.write_all(&buf)?;
    
    Ok(())
}

fn main() -> std::io::Result<()> {

    let mut f = std::fs::File::create("foo.txt")?;
    download(&mut f)?;
    
    Ok(())
}

playground link

对于大文件,我认为此解决方案可能会消耗大量内存,我宁愿将每个 block 直接写入文件中,而无需任何中间缓冲区。我看到有write_at在文档中,但是这种方法对于unix系统是唯一的吗?我正在寻找通用的解决方案。

直觉上,我希望这样的东西能够工作:

use rand::prelude::*;
use rand; // 0.7.3

fn download<W: std::io::Write>(writer: &mut W) -> std::io::Result<()>
{
    // the size (20) is known
    writer.reserve(20)?;

    // simulate downloading four 5 byte chunks at random disjoint slices in *buf*
    for n in (0..20).step_by(5).collect::<Vec<usize>>().choose_multiple(&mut thread_rng(), 4) {
        let n = *n as usize;
        let chunk: [u8; 5] = rand::random();
        writer.write_at(chunk, n)?;
    }

    Ok(())
}

fn main() -> std::io::Result<()> {

    let mut f = std::fs::File::create("foo.txt")?;
    download(&mut f)?;

    Ok(())
}

是否有专门用于写入随机访问文件输出的方法?我可以使用内存映射文件吗?快速搜索我只能找到 positioned-io crate,已经三年没有更新了。 rust 标准库中有类似这个 crate 的东西吗?

最佳答案

您正在寻找 Seek File实现 SeekWrite所以你只需要绑定(bind) Seek还有:

use std::io::{Write, Seek, SeekFrom, Result as IoResult};

fn download<W: Write + Seek>(writer: &mut W) -> IoResult<()> { /* ... */ }

现在你可以做writer.seek(SeekFrom::Start(*n as u64 * CHUNK_SIZE))?;在写出 block 之前。

关于rust - 写入带有偏移量的静态大小文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73071097/

相关文章:

stack-overflow - 任务 'rustc' 已溢出其堆栈

concurrency - 如果做错了,为什么用餐哲学家不会陷入僵局?

reference - CString::new().unwrap().as_ptr() 给出空的 *const c_char

functional-programming - 函数式编程的开销

rust - 是否可以返回在函数范围内创建的引用?

rust - 使用 src 文件夹中的模块内部模块

performance - 在 future-rs 中封装阻塞 I/O 的最佳方法是什么?

rust - 具有对其他结构的不可变引用的结构

rust - 调用函数时移动所有权是否会复制 `self` 结构?

timer - Rust 是否有 Python 的 threading.Timer 的等价物?