Trait std::io::Read

1.0.0 · source ·
pub trait Read {
    // Required method
    fn read(&mut self, buf: &mut [u8]) -> Result<usize>;

    // Provided methods
    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> { ... }
    fn is_read_vectored(&self) -> bool { ... }
    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> { ... }
    fn read_to_string(&mut self, buf: &mut String) -> Result<usize> { ... }
    fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> { ... }
    fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<()> { ... }
    fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<()> { ... }
    fn by_ref(&mut self) -> &mut Self
       where Self: Sized { ... }
    fn bytes(self) -> Bytes<Self> 
       where Self: Sized { ... }
    fn chain<R: Read>(self, next: R) -> Chain<Self, R> 
       where Self: Sized { ... }
    fn take(self, limit: u64) -> Take<Self> 
       where Self: Sized { ... }
}
Expand description

Read trait 允许从源读取字节。

Read trait 的实现者称为 ‘readers’。

Readers 由一种必需的方法 read() 定义。对 read() 的每次调用都会尝试将字节从此源拉入提供的缓冲区。 read() 还实现了许多其他方法,从而为实现者提供了多种读取字节的方式,而只需要实现一种方法即可。

Readers 旨在彼此组成。std::io 上的许多实现器都采用并提供实现 Read trait 的类型。

请注意,对 read() 的每次调用都可能涉及一个系统调用,因此,使用实现 BufRead 的东西 (例如 BufReader) 会更加有效。

Examples

File 的工具 Read

use std::io;
use std::io::prelude::*;
use std::fs::File;

fn main() -> io::Result<()> {
    let mut f = File::open("foo.txt")?;
    let mut buffer = [0; 10];

    // 最多读取 10 个字节
    f.read(&mut buffer)?;

    let mut buffer = Vec::new();
    // 读取整个文件
    f.read_to_end(&mut buffer)?;

    // 读入一个字符串,这样就不需要进行转换。
    let mut buffer = String::new();
    f.read_to_string(&mut buffer)?;

    // 和更多! 有关更多详细信息,请参见其他方法。
    Ok(())
}
Run

&str 读取,因为 &[u8] 实现了 Read

use std::io::prelude::*;

fn main() -> io::Result<()> {
    let mut b = "This string will be read".as_bytes();
    let mut buffer = [0; 10];

    // 最多读取 10 个字节
    b.read(&mut buffer)?;

    // 等等... 它的工作原理与文件一样!
    Ok(())
}
Run

Required Methods§

source

fn read(&mut self, buf: &mut [u8]) -> Result<usize>

从该源中提取一些字节到指定的缓冲区中,返回读取的字节数。

该函数不提供有关是否阻塞等待数据的任何保证,但是如果对象需要阻塞读取而不能阻塞,则通常会通过 Err 返回值来发出信号。

如果此方法的返回值为 Ok(n),则实现必须保证 0 <= n <= buf.len()n 值非零表示缓冲区 buf 已填充有来自该源的 n 字节的数据。 如果 n0,则它可以指示以下两种情况之一:

  1. reader 已到达其 “文件结尾”,可能不再能够产生字节。请注意,这并不意味着 reader 总是会不再能够生成字节。 例如,在 Linux 上,此方法将调用 TcpStreamrecv 系统调用,其中返回零表示连接已正确关闭。 而对于 File,有可能到达文件末尾并得到零作为结果,但如果向文件追加更多数据,那么将来对 read 的调用将返回更多数据。
  2. 指定的缓冲区的长度为 0 个字节。

如果返回值 n 小于缓冲区大小,即使 reader 不在流的末尾,也不会出错。 例如,这可能是因为现在实际可用的字节较少 (例如,接近文件末尾) 或 read() 被信号中断。

由于此 trait 可以安全实现,因此不安全代码中的调用者不能依赖 n <= buf.len() 来确保安全。 当使用 unsafe 函数访问读取的字节时,需要格外小心。 调用者必须确保即使 n > buf.len() 也不能进行未经检查的越界访问。

调用此函数时,不保证 buf 的内容,因此实现不能依赖于 buf 内容的任何属性为真。 建议 implementations 仅将数据写入 buf,而不要读取其内容。

然而,相应地,不安全代码中此方法的调用者不得对实现如何使用 buf 做出任何保证。 这个 trait 可以安全地实现,所以应该写入缓冲区的代码也有可能从中读取。 您有责任在调用 read 之前确保 buf 已初始化。 用未初始化的 buf (通过 MaybeUninit<T> 获得的那种) 来调用 read 是不安全的,并且可能导致未定义的行为。

Errors

如果此函数遇到任何形式的 I/O 或其他错误,将返回一个错误变体。如果返回错误,则必须保证未读取任何字节。

ErrorKind::Interrupted 类型的错误是非致命错误,如果没有其他事情可做,则应重试读取操作。

Examples

File 的工具 Read

use std::io;
use std::io::prelude::*;
use std::fs::File;

fn main() -> io::Result<()> {
    let mut f = File::open("foo.txt")?;
    let mut buffer = [0; 10];

    // 最多读取 10 个字节
    let n = f.read(&mut buffer[..])?;

    println!("The bytes: {:?}", &buffer[..n]);
    Ok(())
}
Run

Provided Methods§

1.36.0 · source

fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize>

read 相似,不同之处在于它读入缓冲区的一部分。

复制数据以按顺序填充每个缓冲区,而写入的最终缓冲区可能仅被部分填充。 此方法必须等效于使用级联缓冲区对 read 的单个调用。

默认实现使用提供的第一个非空缓冲区调用 read,如果不存在,则为空。

source

fn is_read_vectored(&self) -> bool

🔬This is a nightly-only experimental API. (can_vector #69941)

确定此 Read 是否具有有效的 read_vectored 实现。

如果 Read 没有覆盖默认的 read_vectored 实现,则使用它的代码可能希望完全避免使用该方法,并合并写入单个缓冲区以提高性能。

默认实现返回 false

source

fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize>

读取所有字节,直到此源中的 EOF 为止,然后将它们放入 buf

从该源读取的所有字节都将追加到指定的缓冲区 buf。 该函数将不断调用 read() 来向 buf 追加更多的数据,直到 read() 返回 Ok(0) 或非 ErrorKind::Interrupted 类型的错误为止。

如果成功,此函数将返回读取的字节总数。

Errors

如果此函数遇到 ErrorKind::Interrupted 类型的错误,则该错误将被忽略,并且操作将继续。

如果遇到任何其他读取错误,则此函数立即返回。任何已经读取的字节都将被追加到 buf

Examples

File 的工具 Read

use std::io;
use std::io::prelude::*;
use std::fs::File;

fn main() -> io::Result<()> {
    let mut f = File::open("foo.txt")?;
    let mut buffer = Vec::new();

    // 读取整个文件
    f.read_to_end(&mut buffer)?;
    Ok(())
}
Run

(有关读取文件的信息,另请参见 std::fs::read 便利函数。)

source

fn read_to_string(&mut self, buf: &mut String) -> Result<usize>

读取这个源中的所有字节,直到 EOF 为止,然后将它们追加到 buf

如果成功,则此函数返回已读取并追加到 buf 的字节数。

Errors

如果此流中的数据 不是 有效的 UTF-8,则返回错误,并且 buf 不变。

有关其他错误语义,请参见 read_to_end

Examples

File 的工具 Read

use std::io;
use std::io::prelude::*;
use std::fs::File;

fn main() -> io::Result<()> {
    let mut f = File::open("foo.txt")?;
    let mut buffer = String::new();

    f.read_to_string(&mut buffer)?;
    Ok(())
}
Run

(有关读取文件的信息,另请参见 std::fs::read_to_string 便利函数。)

1.6.0 · source

fn read_exact(&mut self, buf: &mut [u8]) -> Result<()>

读取填充 buf 所需的确切字节数。

该函数读取所需的字节数以完全填充指定的缓冲区 buf

调用此函数时,不保证 buf 的内容,因此实现不能依赖于 buf 内容的任何属性为真。 建议实现仅将数据写入 buf,而不读取其内容。 read 上的文档对此主题有更详细的说明。

Errors

如果此函数遇到 ErrorKind::Interrupted 类型的错误,则该错误将被忽略,并且操作将继续。

如果此函数在完全填充缓冲区之前遇到 “文件结尾”,它将返回 ErrorKind::UnexpectedEof 类型的错误。 在这种情况下,buf 的内容未指定。

如果遇到任何其他读取错误,则此函数立即返回。在这种情况下,buf 的内容未指定。

如果此函数返回错误,则无法确定已读取多少字节,但读取的字节数永远不会超过完全填充缓冲区所需的字节数。

Examples

File 的工具 Read

use std::io;
use std::io::prelude::*;
use std::fs::File;

fn main() -> io::Result<()> {
    let mut f = File::open("foo.txt")?;
    let mut buffer = [0; 10];

    // 精确读取 10 个字节
    f.read_exact(&mut buffer)?;
    Ok(())
}
Run
source

fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<()>

🔬This is a nightly-only experimental API. (read_buf #78485)

从此源中提取一些字节到指定的缓冲区中。

这等效于 read 方法,只是它传递的是 BorrowedCursor 而不是 [u8] 以允许与未初始化的缓冲区一起使用。 新的数据将被追加到 buf 的任何现有内容中。

默认实现委托给 read

source

fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<()>

🔬This is a nightly-only experimental API. (read_buf #78485)

读取填充 cursor 所需的确切字节数。

这类似于 read_exact 方法,除了它传递的是 BorrowedCursor 而不是 [u8] 以允许使用未初始化的缓冲区。

Errors

如果此函数遇到 ErrorKind::Interrupted 类型的错误,则该错误将被忽略,并且操作将继续。

如果此函数在完全填充缓冲区之前遇到 “文件结尾”,它将返回 ErrorKind::UnexpectedEof 类型的错误。

如果遇到任何其他读取错误,则此函数立即返回。

如果此函数返回错误,则读取的所有字节都将,到 cursor

source

fn by_ref(&mut self) -> &mut Selfwhere Self: Sized,

为这个 Read 实例创建一个 “by reference” 适配器。

返回的适配器也实现了 Read,并且将简单地借用当前的 reader。

Examples

File 的工具 Read

use std::io;
use std::io::Read;
use std::fs::File;

fn main() -> io::Result<()> {
    let mut f = File::open("foo.txt")?;
    let mut buffer = Vec::new();
    let mut other_buffer = Vec::new();

    {
        let reference = f.by_ref();

        // 最多读取 5 个字节
        reference.take(5).read_to_end(&mut buffer)?;

    } // 丢弃 &mut 引用,以便我们可以再次使用 f

    // 原始文件仍然可用,请读取其余内容
    f.read_to_end(&mut other_buffer)?;
    Ok(())
}
Run
source

fn bytes(self) -> Bytes<Self> where Self: Sized,

将此 Read 实例的字节数转换为 Iterator

返回的类型实现 Iterator,其中 ItemResult<u8, io::Error>。 如果成功读取了一个字节,则产生的项为 Ok,否则为 Err。 EOF 映射为从此迭代器返回 None

默认实现为每个字节调用 read,这对于不在内存中的数据 (例如 File) 可能非常低效。

在这种情况下考虑使用 BufReader

Examples

File 的工具 Read

use std::io;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::File;

fn main() -> io::Result<()> {
    let f = BufReader::new(File::open("foo.txt")?);

    for byte in f.bytes() {
        println!("{}", byte.unwrap());
    }
    Ok(())
}
Run
source

fn chain<R: Read>(self, next: R) -> Chain<Self, R> where Self: Sized,

创建一个适配器,将这个流与另一个链接起来。

返回的 Read 实例将首先从该对象读取所有字节,直到遇到 EOF。 之后,输出等同于 next 的输出。

Examples

File 的工具 Read

use std::io;
use std::io::prelude::*;
use std::fs::File;

fn main() -> io::Result<()> {
    let f1 = File::open("foo.txt")?;
    let f2 = File::open("bar.txt")?;

    let mut handle = f1.chain(f2);
    let mut buffer = String::new();

    // 将值读入字符串。
    // 我们可以在这里使用任何 Read 方法,这只是一个示例。
    handle.read_to_string(&mut buffer)?;
    Ok(())
}
Run
source

fn take(self, limit: u64) -> Take<Self> where Self: Sized,

创建一个适配器,最多从中读取 limit 个字节。

此函数返回 Read 的新实例,该实例最多读取 limit 字节,此后它将始终返回 EOF (Ok(0))。 任何读取错误都不会计入读取的字节数,并且 read() 的 future 调用可能会成功。

Examples

File 的工具 Read

use std::io;
use std::io::prelude::*;
use std::fs::File;

fn main() -> io::Result<()> {
    let f = File::open("foo.txt")?;
    let mut buffer = [0; 5];

    // 最多读取五个字节
    let mut handle = f.take(5);

    handle.read(&mut buffer)?;
    Ok(())
}
Run

Implementors§

source§

impl Read for &File

source§

impl Read for &TcpStream

source§

impl Read for &[u8]

通过从切片复制为 &[u8] 实现读取。

请注意,读取将更新切片以指向尚未读取的部分。 到达 EOF 时,切片将为空。

source§

impl Read for File

source§

impl Read for TcpStream

1.10.0 · source§

impl Read for UnixStream

Available on Unix only.
source§

impl Read for ChildStderr

source§

impl Read for ChildStdout

source§

impl Read for Empty

source§

impl Read for Repeat

source§

impl Read for Stdin

source§

impl Read for StdinLock<'_>

1.10.0 · source§

impl<'a> Read for &'a UnixStream

Available on Unix only.
1.63.0 · source§

impl<A: Allocator> Read for VecDeque<u8, A>

VecDeque<u8> 通过消耗 VecDeque 前面的字节来实现读取。

source§

impl<R: Read + ?Sized> Read for &mut R

source§

impl<R: Read + ?Sized> Read for Box<R>

source§

impl<R: Read> Read for BufReader<R>

source§

impl<T> Read for Cursor<T>where T: AsRef<[u8]>,

source§

impl<T: Read> Read for Take<T>

source§

impl<T: Read, U: Read> Read for Chain<T, U>