【问题标题】:How to skip N bytes with Read without allocation? [duplicate]如何在不分配的情况下使用 Read 跳过 N 个字节? [复制]
【发布时间】:2020-01-20 15:20:02
【问题描述】:

我想在使用Read 实例而不进行任何分配时跳过任意数量的字节。跳过后,我需要继续阅读后面的数据。

编译时不知道字节数,所以我无法创建固定数组。 Read 也没有跳过,所以我似乎需要阅读一些内容。我不想使用BufReader 并分配不必要的缓冲区,也不想逐字节读取,因为这样效率低下。

还有其他选择吗?

【问题讨论】:

  • 没有,你应该忘记它,简短的版本是你需要一个缓冲区(堆栈或堆,没关系,但我建议你堆),因为你是用户所以在用户空间,内核将永远不允许任何用户代码在内核空间中运行,因此您需要一个缓冲区。此外,无论如何,就像您将在某些时候使用您的数据一样,您将需要一个缓冲区,所以答案是使用缓冲区。
  • @Stargateur 我使用过二进制协议,我实际上并不关心部分数据(但我知道它有多大)。这似乎是其中一种情况。
  • 我只会读入堆栈上的一个数组(如果数组不够大,则在循环中)。所述数组的大小取决于您的平台和用例,但我可能会默认使用 1KB,除非我有充分的理由更好地调整它。
  • 逐字节读取可能效率低下对于已经有内部缓冲区的流。如果没有缓冲区,逐字节是您可以读取流的唯一方式(除非它碰巧也实现了Seek,正如 Shepmaster 的回答所指出的那样)。
  • @Stargateur“无论如何,你会在某个时候使用你的数据”......不。这正是提出这个问题的原因,因为我绝对不需要它并希望避免时间和空间的影响。

标签: rust


【解决方案1】:

最好的办法是同时要求Seek

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

fn example(mut r: impl Read + Seek) -> io::Result<String> {
    r.seek(SeekFrom::Current(5))?;

    let mut s = String::new();
    r.take(5).read_to_string(&mut s)?;

    Ok(s)
}

#[test]
fn it_works() -> io::Result<()> {
    use std::io::Cursor;

    let s = example(Cursor::new("abcdefghijklmnop"))?;
    assert_eq!("fghij", s);
    Ok(())
}

如果您不能使用Seek,请查看How to advance through data from the std::io::Read trait when Seek isn't implemented?

另见:

【讨论】:

  • 似乎一次性缓冲区是执行此操作的唯一方法,因此来自链接的io::copy
猜你喜欢
  • 2021-06-11
  • 2014-07-10
  • 1970-01-01
  • 2013-09-30
  • 1970-01-01
  • 1970-01-01
  • 2018-06-24
  • 1970-01-01
  • 2012-05-15
相关资源
最近更新 更多