Byte stream types like TcpStream manage their own buffers internally. Instead of passing a buffer to a read method, you interact with the stream using buffered I/O patterns (implementing AsyncBufRead).
Standard Buffered I/O
Use fill_buf() to get a view of the internal buffer and consume() to mark data as processed.
Zero-copy Piping
For high-performance data transfer between two streams, use take_read_buf() to extract an IoBuf from a source stream and place_write_buf() to provide it to a destination stream.
File Streams
Unlike TcpStream, the File type does not provide a single byte stream. Instead, you request specific read_stream() or write_stream() handles. These streams maintain their own cursors, allowing for concurrent positional I/O on the same file.
// Standard buffered I/O pattern
let data: &[u8] = my_stream.fill_buf().await?;
my_stream.consume(data.len());
// Zero-copy piping pattern
my_tcp_stream.fill_buf().await?;
let buf: IoBuf = my_tcp_stream.take_read_buf();
// ... mutate buf if needed ...
my_other_stream.place_write_buf(buf);
my_other_stream.flush().await?;
// File stream pattern
let read_stream = my_file.read_stream();
let write_stream = my_file.write_stream();
let buf: IoBuf = read_stream.take_read_buf().await?;
write_stream.place_write_buf(buf).await?;
write_stream.flush().await?;