Introducción
En este laboratorio, se introduce el módulo std::fs de Rust, que proporciona funciones para las operaciones del sistema de archivos. El laboratorio presenta ejemplos de diversas operaciones del sistema de archivos, incluyendo la creación de directorios, la creación de archivos, la lectura del contenido de archivos, la creación de enlaces simbólicos, la lista del contenido de un directorio, la eliminación de archivos y la eliminación de directorios. Los fragmentos de código demuestran cómo realizar estas operaciones utilizando las funciones del módulo std::fs, y se proporciona la salida esperada para cada operación. Además, se menciona una implementación alternativa de la función cat que utiliza la notación ? para el manejo de errores.
Nota: Si el laboratorio no especifica un nombre de archivo, puede utilizar cualquier nombre de archivo que desee. Por ejemplo, puede utilizar
main.rs, compilar y ejecutarlo conrustc main.rs &&./main.
Operaciones del sistema de archivos
El módulo std::fs contiene varias funciones que se ocupan del sistema de archivos.
use std::fs;
use std::fs::{File, OpenOptions};
use std::io;
use std::io::prelude::*;
use std::os::unix;
use std::path::Path;
// Una implementación simple de `% cat path`
fn cat(path: &Path) -> io::Result<String> {
let mut f = File::open(path)?;
let mut s = String::new();
match f.read_to_string(&mut s) {
Ok(_) => Ok(s),
Err(e) => Err(e),
}
}
// Una implementación simple de `% echo s > path`
fn echo(s: &str, path: &Path) -> io::Result<()> {
let mut f = File::create(path)?;
f.write_all(s.as_bytes())
}
// Una implementación simple de `% touch path` (ignora archivos existentes)
fn touch(path: &Path) -> io::Result<()> {
match OpenOptions::new().create(true).write(true).open(path) {
Ok(_) => Ok(()),
Err(e) => Err(e),
}
}
fn main() {
println!("`mkdir a`");
// Crea un directorio, devuelve `io::Result<()>`
match fs::create_dir("a") {
Err(why) => println!("! {:?}", why.kind()),
Ok(_) => {},
}
println!("`echo hello > a/b.txt`");
// La coincidencia anterior se puede simplificar utilizando el método `unwrap_or_else`
echo("hello", &Path::new("a/b.txt")).unwrap_or_else(|why| {
println!("! {:?}", why.kind());
});
println!("`mkdir -p a/c/d`");
// Crea un directorio de forma recursiva, devuelve `io::Result<()>`
fs::create_dir_all("a/c/d").unwrap_or_else(|why| {
println!("! {:?}", why.kind());
});
println!("`touch a/c/e.txt`");
touch(&Path::new("a/c/e.txt")).unwrap_or_else(|why| {
println!("! {:?}", why.kind());
});
println!("`ln -s../b.txt a/c/b.txt`");
// Crea un enlace simbólico, devuelve `io::Result<()>`
if cfg!(target_family = "unix") {
unix::fs::symlink("../b.txt", "a/c/b.txt").unwrap_or_else(|why| {
println!("! {:?}", why.kind());
});
}
println!("`cat a/c/b.txt`");
match cat(&Path::new("a/c/b.txt")) {
Err(why) => println!("! {:?}", why.kind()),
Ok(s) => println!("> {}", s),
}
println!("`ls a`");
// Lee el contenido de un directorio, devuelve `io::Result<Vec<Path>>`
match fs::read_dir("a") {
Err(why) => println!("! {:?}", why.kind()),
Ok(paths) => for path in paths {
println!("> {:?}", path.unwrap().path());
},
}
println!("`rm a/c/e.txt`");
// Elimina un archivo, devuelve `io::Result<()>`
fs::remove_file("a/c/e.txt").unwrap_or_else(|why| {
println!("! {:?}", why.kind());
});
println!("`rmdir a/c/d`");
// Elimina un directorio vacío, devuelve `io::Result<()>`
fs::remove_dir("a/c/d").unwrap_or_else(|why| {
println!("! {:?}", why.kind());
});
}
A continuación se muestra la salida exitosa esperada:
$ rustc fs.rs && ./fs
$(mkdir a)
$(echo hello > a/b.txt)
$(mkdir -p a/c/d)
$(touch a/c/e.txt)
$(ln -s../b.txt a/c/b.txt)
$(cat a/c/b.txt)
> hello
$(ls a)
> "a/b.txt"
> "a/c"
$(rm a/c/e.txt)
$(rmdir a/c/d)
Y el estado final del directorio a es:
$ tree a
a
|-- b.txt
`-- c
`-- b.txt ->../b.txt
1 directorio, 2 archivos
Una forma alternativa de definir la función cat es con la notación ?:
fn cat(path: &Path) -> io::Result<String> {
let mut f = File::open(path)?;
let mut s = String::new();
f.read_to_string(&mut s)?;
Ok(s)
}
Resumen
¡Felicidades! Has completado el laboratorio de Operaciones del sistema de archivos. Puedes practicar más laboratorios en LabEx para mejorar tus habilidades.