Escribir un archivo de texto en Rust son tres líneas si solo quieres volcar una cadena, y poco más si necesitas ir escribiendo línea a línea o añadir al final de un archivo que ya existe. Todo lo de esta página es biblioteca estándar: no hace falta añadir ninguna dependencia.
También te puede interesar
La forma corta: fs::write
Si lo que tienes es una cadena entera y quieres dejarla en disco, hay una sola llamada que crea el archivo, escribe y lo cierra. Si el archivo ya existía, lo reemplaza por completo.
use std::fs;
fn main() -> std::io::Result<()> {
fs::write("notas.txt", "La primera línea\nLa segunda línea\n")?;
println!("archivo escrito");
Ok(())
}
notas.txtLa primera línea La segunda línea
Fíjate en dos detalles de la firma. El ? después de la llamada propaga el error si algo falla, por ejemplo si no hay permisos de escritura en esa carpeta. Y para que ese ? sea legal, main declara que devuelve std::io::Result<()> y termina con Ok(()). Es el mismo mecanismo que explicamos en la lección de manejo de errores.
Línea a línea: File y BufWriter
Cuando el contenido se va generando sobre la marcha, conviene abrir el archivo una vez e ir escribiendo. BufWriter acumula en memoria y vuelca de golpe, lo que evita una llamada al sistema por cada línea:
use std::fs::File;
use std::io::{BufWriter, Write};
fn main() -> std::io::Result<()> {
let archivo = File::create("inventario.txt")?;
let mut salida = BufWriter::new(archivo);
let articulos = [("tornillos", 120), ("tuercas", 80), ("arandelas", 45)];
for (nombre, cantidad) in articulos {
writeln!(salida, "{nombre};{cantidad}")?;
}
salida.flush()?;
println!("{} líneas escritas", articulos.len());
Ok(())
}
inventario.txttornillos;120 tuercas;80 arandelas;45
writeln! funciona igual que println! pero recibe como primer argumento el destino. Y el flush() del final fuerza el volcado de lo que quede en el búfer: Rust también lo hace al destruir el BufWriter, pero hacerlo explícitamente permite detectar un error de escritura, que de la otra forma se perdería en silencio.
Añadir al final sin borrar lo anterior
File::create siempre vacía el archivo. Para conservar el contenido y escribir detrás, hay que abrirlo con opciones:
use std::fs::OpenOptions;
use std::io::Write;
fn main() -> std::io::Result<()> {
let mut registro = OpenOptions::new()
.create(true)
.append(true)
.open("registro.log")?;
writeln!(registro, "arranque correcto")?;
println!("línea añadida al final");
Ok(())
}
create(true) lo crea si no existe y append(true) coloca el cursor al final. Ejecutando ese programa tres veces, el archivo acaba así:
registro.log tras tres ejecucionesarranque correcto arranque correcto arranque correcto
Cuál usar
| Situación | Qué usar |
|---|---|
| Tengo la cadena entera y quiero volcarla | fs::write |
| Voy generando el contenido línea a línea | File::create + BufWriter |
| Quiero añadir sin borrar lo anterior | OpenOptions con append(true) |
| Son datos binarios, no texto | write_all con un &[u8] |
writeln! sobre un File y olvidas importar el trait, el programa no compila: sale error[E0599]: cannot write into `File` con la nota «must implement io::Write». No es que falte el método, es que vive en un trait que hay que traer al ámbito. Basta con añadir use std::io::Write;, cosa que el propio compilador sugiere en el mensaje. Es la mecánica de los traits que explicamos en la lección 8.Todo el código de esta página se compiló y ejecutó con rustc 1.96.1 antes de publicarla; las salidas están copiadas de la ejecución real. Documentación oficial: std::fs::write, BufWriter y OpenOptions.