Lire et écrire des fichiers en Rust 1.x : approches de facto

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Rust et les fichiers : mythes, peurs et approches de facto

Vous êtes-vous déjà demandé : « Comment lire et écrire correctement des fichiers dans le Rust moderne ? ». Si oui, vous n'êtes pas seul. Sur Stack Overflow, la question « What's the de-facto way of reading and writing files in Rust 1.x? » a rassemblé des milliers de vues et des dizaines de réponses. C'est une vraie difficulté pour la communauté, surtout pour ceux qui viennent de Python ou JavaScript, où open() et read() sont la base, alors qu'en Rust il faut comprendre la possession, l'emprunt et une multitude de traits.

Dans cet article, nous allons détailler toutes les méthodes principales pour travailler avec les fichiers en Rust 1.x : de « lire simplement tout dans une chaîne » à la lecture ligne par ligne efficace de gros fichiers journaux. Vous découvrirez quelle approche est considérée comme idiomatique et laquelle est préférable de réserver pour des cas particuliers. C'est parti !



1. std::fs : l'arsenal standard

Le module std::fs est votre premier arrêt. Il fournit des fonctions pour lire, écrire, copier et supprimer des fichiers. Rust 1.x a stabilisé des wrappers pratiques qui cachent la majeure partie du travail de bas niveau avec les appels système.



Lire tout le fichier dans une chaîne

La méthode la plus simple est d'utiliser std::fs::read_to_string. Il ouvre le fichier, le lit entièrement en mémoire et retourne un Result<String>. Idéal pour les petits fichiers de configuration ou les fichiers texte.

use std::fs;

fn main() -> std::io::Result<()> { let content = fs::read_to_string("hello.txt")?; println!("Le fichier contient :{}", content); Ok(())}

Cette méthode est la norme de facto pour les cas simples. Elle est concise, sûre et utilise ? pour la gestion des erreurs. Le seul inconvénient est que tout le fichier est chargé en mémoire, donc elle ne convient pas pour les fichiers journaux de plusieurs gigaoctets.



Lire dans un vecteur d'octets

Si vous travaillez avec des données binaires (images, archives), utilisez std::fs::read. Il retourne un Vec<u8>.

use std::fs;

fn main() -> std::io::Result<()> { let bytes = fs::read("image.png")?; println!("Lu {} octets", bytes.len()); Ok(())}


Écrire dans un fichier

Pour écrire, utilisez std::fs::write. Il prend un chemin et des données (une chaîne ou un tableau d'octets) et crée/remplace le fichier.

use std::fs;

fn main() -> std::io::Result<()> { fs::write("output.txt", "Bonjour, Rust !")?; Ok(())}

Simple comme bonjour. Mais si vous devez ajouter à la fin du fichier au lieu de le remplacer, vous devrez utiliser OpenOptions.



2. BufReader et BufWriter : quand la taille compte

Pour les gros fichiers ou les opérations d'entrée-sortie fréquentes, les wrappers bufferisés viennent à la rescousse. Ils réduisent le nombre d'appels système, ce qui est crucial pour les performances.



Lecture ligne par ligne avec BufReader

Un exemple classique est la lecture ligne par ligne d'un gros fichier journal :

use std::fs::File;use std::io::{BufRead, BufReader};

fn main() -> std::io::Result<()> { let file = File::open("large_log.txt")?; let reader = BufReader::new(file);

for line in reader.lines() { let line = line?; println!("{}", line); } Ok(())}

La méthode lines() retourne un itérateur de lignes, chacune étant un Result<String>. Notez le line? à l'intérieur de la boucle — c'est la gestion des erreurs de lecture de chaque ligne.

Important : lines() supprime les caractères de saut de ligne. Si vous devez les conserver, utilisez read_until ou lisez le fichier comme Vec<u8>.



Écrire avec BufWriter

Lors de l'écriture de gros volumes de données, la bufferisation est également utile :

use std::fs::File;use std::io::{BufWriter, Write};

fn main() -> std::io::Result<

Blogs

Book Recommendations