rust 从文件中读取一定范围字节的最惯用方法

hsvhsicv  于 2023-08-05  发布在  其他
关注(0)|答案(2)|浏览(167)

我有一个文件,比如说myfile。使用Rust,我想打开myfile,并将字节N到M读取到Vec中,例如myvec。“最惯用的方法是什么?天真地,我想到了使用bytes(),然后是skiptakecollect,但这听起来太低效了。

qacovj5a

qacovj5a1#

  • 最惯用的 *(据我所知)和相对有效的方法:
let start = 10;
let count = 10;

let mut f = File::open("/etc/passwd")?;
f.seek(SeekFrom::Start(start))?;
let mut buf = vec![0; count];
f.read_exact(&mut buf)?;

字符串
您在注解中指出,您担心在阅读内存之前将内存归零的开销。实际上,这样做的成本不是零,但与从文件读取所需的I/O操作相比,它通常可以忽略不计,其优点是您的代码保持100%可靠。但仅出于教育目的,我试图提出一种避免归零的方法。
不幸的是,即使使用不安全的代码,我们也不能安全地将未初始化的缓冲区传递给read_exact,因为文档中的这一段(强调我的):
当调用此函数时,不提供有关buf内容的保证,实现不能依赖于buf内容的任何属性为true。建议实现只向buf写入数据,不阅读内容。
所以从技术上讲,File::read_exact从提供的缓冲区 * 读取 * 是法律的的,这意味着我们不能在这里合法地传递未初始化的数据(使用MaybeUninit)。

bxjv4tth

bxjv4tth2#

现有的答案可以工作,但它会将您所要查找的整个块读入内存中的Vec。如果你要阅读的块很大,或者你在内存中不需要它,你最好需要一个io::Read,你可以直接复制到另一个文件或传递到另一个API。
如果你的源代码实现了Read + Seek,那么你可以查找到起始位置,然后使用Read::take只读取特定数量的字节。

use std::{fs::File, io::{self, Read, Seek, SeekFrom}};

let start = 20;
let length = 100;

let mut input = File::open("input.bin")?;

// Seek to the start position
input.seek(SeekFrom::Start(start))?;

// Create a reader with a fixed length    
let mut chunk = input.take(length);

let mut output = File::create("output.bin")?;

// Copy the chunk into the output file
io::copy(&mut chunk, &mut output)?;

字符串

相关问题