Arbeiten mit CSV in Rust: Bibliotheken, Codebeispiele und bewährte Praktiken
CSV (Comma-Separated Values) ist eines der am weitesten verbreiteten Formate zur Speicherung von Tabellendaten. Im Rust-Ökosystem gibt es die leistungsstarke und flexible Bibliothek csv, die in Kombination mit der Crate serde das bequeme Lesen, Schreiben und Transformieren von CSV-Daten ermöglicht. In diesem Artikel werden wir detailliert besprechen, wie man mit CSV in Rust arbeitet, angefangen beim grundlegenden Parsing bis hin zur Serialisierung komplexer Strukturen.
Installation und Einbindung von Abhängigkeiten
Fügen Sie zunächst die folgenden Abhängigkeiten zu Ihrer Cargo.toml-Datei hinzu:
[dependencies]csv = "1.3"serde = { version = "1.0", features = ["derive"] }Die Bibliothek csv bietet eine Low-Level-API zum Lesen und Schreiben, während serde die automatische Deserialisierung von CSV-Zeilen in Rust-Strukturen ermöglicht.
CSV-Datei zeilenweise lesen
Der einfachste Weg, eine CSV-Datei zu lesen, ist die Verwendung von Reader aus der Crate csv. Betrachten wir ein Beispiel mit der Datei users.csv:
use csv::Reader;use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> { let mut rdr = Reader::from_path("users.csv")?;
for result in rdr.records() { let record = result?; println!("{:?}", record); } Ok(())}Dieser Code gibt jede Zeile als Vektor von Zeichenketten StringRecord aus. In der Praxis arbeitet man jedoch häufiger mit typisierten Daten.
Deserialisierung in Strukturen mit serde
Deklarieren wir eine Struktur, die den CSV-Spalten entspricht:
use serde::Deserialize;
#[derive(Debug, Deserialize)]struct User { name: String, age: u32, city: String,}Jetzt können Datensätze direkt in User-Instanzen gelesen werden:
use csv::Reader;use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> { let mut rdr = Reader::from_path("users.csv")?;
for result in rdr.deserialize() { let user: User = result?; println!("{} ({} Jahre) aus {}", user.name, user.age, user.city); } Ok(())}Die Bibliothek ordnet automatisch die CSV-Header den Feldern der Struktur zu. Wenn die Reihenfolge oder die Namen der Spalten abweichen, verwenden Sie das Attribut #[serde(rename = "...")].
CSV-Datei schreiben
Das Erstellen einer CSV-Datei erfolgt mit Writer. Das Schreiben strukturierter Daten über serde:
use csv::Writer;use serde::Serialize;use std::error::Error;
#[derive(Debug, Serialize)]struct Product { id: u32, name: String, price: f64,}
fn main() -> Result<(), Box<dyn Error>> { let mut wtr = Writer::from_path("products.csv")?;
let products = vec![ Product { id: 1, name: "Laptop".into(), price: 75000.0 }, Product { id: 2, name: "Maus".into(), price: 1500.0 }, ];
for product in &products { wtr.serialize(product)?; }
wtr.flush()?; println!("Datei products.csv erfolgreich geschrieben"); Ok(())}Beachten Sie: Der Writer fügt automatisch Header basierend auf den Feldnamen der Struktur hinzu.
Konfiguration von Trennzeichen und Anführungszeichen
Standardmäßig werden Komma und doppelte Anführungszeichen verwendet. Wenn Ihre Datei ein Semikolon verwendet (z. B. in europäischen Locales), konfigurieren Sie ReaderBuilder:
use csv::ReaderBuilder;
let mut rdr = ReaderBuilder::new() .delimiter(b';') .has_headers(true) .from_path("data.tsv")?;Analog wird WriterBuilder zum Schreiben konfiguriert.
Fehlerbehandlung und ungültige Daten
Auch in der Bibliothek
Chronicle Map Java: Komplettleitfaden mit Beispielen
JMH Java: Vollständiges Tutorial mit Beispielen und Tipps
Kotlin Task Scheduler: kotlinx.coroutines und Bibliotheken für Hintergrundaufgaben
FastEndpoints für C# (.NET): Komplettleitfaden mit Beispielen