Spec-Zone.ru › Tokio

Трейт AsyncBufReadExt

pub trait AsyncBufReadExt: AsyncBufRead {
    // Provided methods
    fn read_until<'a>(
        &'a mut self,
        byte: u8,
        buf: &'a mut Vec<u8>,
    ) -> ReadUntil<'a, Self>
       where Self: Unpin { ... }
    fn read_line<'a>(&'a mut self, buf: &'a mut String) -> ReadLine<'a, Self>
       where Self: Unpin { ... }
    fn split(self, byte: u8) -> Split<Self>
       where Self: Sized + Unpin { ... }
    fn fill_buf(&mut self) -> FillBuf<'_, Self>
       where Self: Unpin { ... }
    fn consume(&mut self, amt: usize)
       where Self: Unpin { ... }
    fn lines(self) -> Lines<Self>
       where Self: Sized { ... }
}
Доступен только при включённой функции крейта io-util.

Трейт-расширение, добавляющий полезные методы для типов AsyncBufRead.

Предоставляемые методы

fn read_until<'a>( &'a mut self, byte: u8, buf: &'a mut Vec<u8>, ) -> ReadUntil<'a, Self>
where Self: Unpin,

Считывает все байты в buf до встречи разделителя byte или EOF.

Эквивалентно:

ⓘ
async fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize>;

Эта функция считывает байты из базового потока до встречи разделителя или EOF. После этого все байты вплоть до разделителя включительно (если он найден) добавляются в buf.

В случае успеха эта функция возвращает общее количество считанных байтов.

Если эта функция возвращает Ok(0), поток достиг EOF.

Ошибки

Эта функция игнорирует все случаи ошибки ErrorKind::Interrupted, а в остальных случаях возвращает ошибки, возвращённые методом fill_buf.

При возникновении ошибки ввода-вывода все уже считанные байты будут находиться в buf, а его длина будет соответствующим образом скорректирована.

Безопасность при отмене

Если этот метод используется как ветвь в tokio::select! и первой завершается другая ветвь, часть данных может быть считана. Все частично считанные байты добавляются в buf, а метод можно вызвать снова, чтобы продолжить чтение до byte.

Этот метод возвращает общее количество считанных байтов. Если отменить вызов read_until, а затем вызвать его снова, чтобы продолжить чтение, счётчик будет сброшен.

Примеры

std::io::Cursor — это тип, реализующий BufRead. В этом примере мы используем Cursor, чтобы считывать все байты из среза байтов, разделённые дефисами:

use tokio::io::AsyncBufReadExt;

use std::io::Cursor;

let mut cursor = Cursor::new(b"lorem-ipsum");
let mut buf = vec![];

// cursor is at 'l'
let num_bytes = cursor.read_until(b'-', &mut buf)
    .await
    .expect("reading from cursor won't fail");

assert_eq!(num_bytes, 6);
assert_eq!(buf, b"lorem-");
buf.clear();

// cursor is at 'i'
let num_bytes = cursor.read_until(b'-', &mut buf)
    .await
    .expect("reading from cursor won't fail");

assert_eq!(num_bytes, 5);
assert_eq!(buf, b"ipsum");
buf.clear();

// cursor is at EOF
let num_bytes = cursor.read_until(b'-', &mut buf)
    .await
    .expect("reading from cursor won't fail");
assert_eq!(num_bytes, 0);
assert_eq!(buf, b"");

fn read_line<'a>(&'a mut self, buf: &'a mut String) -> ReadLine<'a, Self>
where Self: Unpin,

Считывает все байты до символа новой строки (байта 0xA) и добавляет их в предоставленный буфер.

Эквивалентно:

ⓘ
async fn read_line(&mut self, buf: &mut String) -> io::Result<usize>;

Эта функция считывает байты из базового потока до разделителя — символа новой строки (байта 0xA) — или до достижения EOF. После этого все байты вплоть до разделителя включительно (если он найден) добавляются в buf.

В случае успеха эта функция возвращает общее количество считанных байтов.

Если эта функция возвращает Ok(0), поток достиг EOF.

Ошибки

Эта функция обрабатывает ошибки так же, как read_until, а также возвращает ошибку, если считанные байты не являются допустимым UTF-8. При возникновении ошибки ввода-вывода buf может содержать уже считанные байты, если все данные, считанные к этому моменту, были допустимым UTF-8.

Безопасность при отмене

Этот метод небезопасен при отмене. Если метод используется как ветвь в tokio::select! и первой завершается другая ветвь, часть данных может быть считана, и эти данные будут потеряны. При отмене вызова содержимое buf не гарантируется. Текущая реализация заменяет buf пустой строкой, но в будущем это может измениться.

Эта функция ведёт себя не так, как read_until, поскольку строка должна содержать только допустимый UTF-8. Если вам нужен безопасный при отмене read_line, есть три варианта:

  • Вызвать read_until с символом новой строки и вручную проверить UTF-8.
  • Поток, возвращаемый методом lines, имеет безопасный при отмене метод next_line.
  • Использовать tokio_util::codec::LinesCodec.
Примеры

std::io::Cursor — это тип, реализующий AsyncBufRead. В этом примере мы используем Cursor, чтобы считывать все строки из среза байтов:

use tokio::io::AsyncBufReadExt;

use std::io::Cursor;

let mut cursor = Cursor::new(b"foo\nbar");
let mut buf = String::new();

// cursor is at 'f'
let num_bytes = cursor.read_line(&mut buf)
    .await
    .expect("reading from cursor won't fail");

assert_eq!(num_bytes, 4);
assert_eq!(buf, "foo\n");
buf.clear();

// cursor is at 'b'
let num_bytes = cursor.read_line(&mut buf)
    .await
    .expect("reading from cursor won't fail");

assert_eq!(num_bytes, 3);
assert_eq!(buf, "bar");
buf.clear();

// cursor is at EOF
let num_bytes = cursor.read_line(&mut buf)
    .await
    .expect("reading from cursor won't fail");

assert_eq!(num_bytes, 0);
assert_eq!(buf, "");

fn split(self, byte: u8) -> Split<Self>
where Self: Sized + Unpin,

Возвращает поток содержимого этого средства чтения, разделённый по байту byte.

Этот метод является асинхронным эквивалентом BufRead::split.

Поток, возвращаемый этой функцией, будет выдавать значения типа io::Result<Option<Vec<u8>>>. В конце каждого возвращённого вектора не будет байта-разделителя.

Ошибки

Для каждого элемента потока действуют те же правила обработки ошибок, что и для AsyncBufReadExt::read_until.

Примеры
use tokio::io::AsyncBufReadExt;

let mut segments = my_buf_read.split(b'f');

while let Some(segment) = segments.next_segment().await? {
    println!("length = {}", segment.len())
}

fn fill_buf(&mut self) -> FillBuf<'_, Self>
where Self: Unpin,

Возвращает содержимое внутреннего буфера, заполняя его дополнительными данными из внутреннего средства чтения, если он пуст.

Эта функция представляет собой низкоуровневый вызов. Для корректной работы её необходимо использовать вместе с методом consume. При вызове этого метода содержимое не считается «прочитанным», поэтому последующий вызов read может вернуть то же содержимое. Таким образом, необходимо вызвать consume с количеством байтов, потреблённых из этого буфера, чтобы эти байты не возвращались повторно.

Возвращение пустого буфера означает, что поток достиг EOF.

Эквивалентно:

ⓘ
async fn fill_buf(&mut self) -> io::Result<&[u8]>;
Ошибки

Эта функция вернёт ошибку ввода-вывода, если при чтении из нижележащего средства чтения произошла ошибка.

Безопасность отмены

Этот метод безопасен при отмене. Если он используется как одна из ветвей в tokio::select!, а другая ветвь завершается первой, гарантируется, что данные не были прочитаны.

fn consume(&mut self, amt: usize)
where Self: Unpin,

Сообщает этому буферу, что из него было потреблено amt байт, поэтому они больше не должны возвращаться при вызовах read.

Эта функция представляет собой низкоуровневый вызов. Для корректной работы её необходимо использовать вместе с методом fill_buf. Эта функция не выполняет ввод-вывод: она лишь сообщает этому объекту, что некоторая часть его буфера, возвращённая методом fill_buf, была потреблена и больше не должна возвращаться. Поэтому эта функция может работать неожиданным образом, если перед её вызовом не был вызван метод fill_buf.

Значение amt должно быть меньше количества байтов в буфере, возвращённом методом fill_buf.

fn lines(self) -> Lines<Self>
where Self: Sized,

Возвращает поток строк этого средства чтения. Этот метод является асинхронным эквивалентом BufRead::lines.

Поток, возвращаемый этой функцией, будет выдавать значения типа io::Result<Option<String>>. В конце каждой возвращённой строки не будет байта новой строки (байта 0xA) или CRLF (байтов 0xD, 0xA).

Ошибки

Для каждой строки потока действуют те же правила обработки ошибок, что и для AsyncBufReadExt::read_line.

Примеры

std::io::Cursor — это тип, реализующий BufRead. В этом примере мы используем Cursor, чтобы перебрать все строки в срезе байтов.

use tokio::io::AsyncBufReadExt;

use std::io::Cursor;

let cursor = Cursor::new(b"lorem\nipsum\r\ndolor");

let mut lines = cursor.lines();

assert_eq!(lines.next_line().await.unwrap(), Some(String::from("lorem")));
assert_eq!(lines.next_line().await.unwrap(), Some(String::from("ipsum")));
assert_eq!(lines.next_line().await.unwrap(), Some(String::from("dolor")));
assert_eq!(lines.next_line().await.unwrap(), None);

Совместимость с dyn

Этот трейт не совместим с dyn.

В более старых версиях Rust совместимость с dyn называлась «безопасностью объектов».

Реализаторы

impl<R: AsyncBufRead + ?Sized> AsyncBufReadExt for R

MIT License
Copyright © Tokio Contributors
https://docs.rs/tokio/1.53.1/tokio/io/trait.AsyncBufReadExt.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API