Readers & Writers: Rasts einheitliches I/O-System
Das Problem: Viele Quellen, viele Ziele
Wo kommen Daten her? Aus Dateien, dem Netzwerk, der Tastatur oder einfach aus
einem Byte-Array im Speicher. Und wo gehen sie hin? In Dateien, ins Netz, auf
die Konsole oder in einen Vec<u8>.
Rust löst das mit zwei Traits, die jede dieser Quellen und Ziele einheitlich machen:
- Reader liefern Bytes. Sie implementieren
std::io::Read. - Writer nehmen Bytes entgegen. Sie implementieren
std::io::Write.
use std::io::Read;
fn main() {
// Ein Reader aus einem Byte-Array im Speicher
let mut reader = std::io::Cursor::new(b"hello, world".to_vec());
let mut buf = String::new();
reader.read_to_string(&mut buf).unwrap();
println!("{buf}"); // hello, world
}
Bekannte Reader
File::open(filename)— bestehende Datei lesenTcpStream— Daten über das Netzwerk empfangenstdin()— Standard-Eingabe des ProzessesCursor<&[u8]>,Cursor<Vec<u8>>— aus einem Byte-Array "lesen"
Bekannte Writer
File::create(filename)— neue Datei schreibenTcpStream— Daten über das Netzwerk sendenstdout(),stderr()— auf den Bildschirm schreibenVec<u8>— derwrite-Methode hängt ans Ende anCursor<Vec<u8>>— lesen und schreiben mit freiem Positionieren
Ein Trait, viele Quellen
Der Zauber: Eine Funktion, die eine generische Read- oder Write-Implementierung
annimmt, funktioniert identisch für Dateien, Netzwerk-Sockets und Buffer.
use std::io::{self, Read};
// Arbeitet mit jeder Quelle, die bytes liefern kann:
fn drucke_inhalt(mut quelle: impl Read) -> io::Result<()> {
let mut text = String::new();
quelle.read_to_string(&mut text)?;
println!("{text}");
Ok(())
}
Läuft für File, TcpStream, Cursor, Stdin — ohne eine Zeile zu ändern.
📝 Schnellprüfung
Welcher Typ IST ein Reader?
✅ Wichtige Erkenntnisse
Haken setzen, um deinen Lernfortschritt zu markieren: