TP 05 - Fichiers et descripteurs de fichiers
Resources
Linux Standard Streams
stdin
est le flux d'entrée standard. Cela accepte le texte comme entrée. La sortie texte de la commande au shell est transmise via le flux stdout
(sortie standard). Les messages d'erreur de la commande sont envoyés via le flux stderr
(erreur standard).
Vous pouvez donc voir qu'il existe deux flux de sortie, stdout
et stderr
, et un flux d'entrée, stdin
. Étant donné que les messages d'erreur et la sortie normale ont chacun leur propre conduit pour les acheminer vers la fenêtre du terminal, ils peuvent être traités indépendamment les uns des autres.
Les flux sous Linux, comme presque tout le reste, sont traités comme s'ils étaient des fichiers. Vous pouvez lire du texte à partir d'un fichier et vous pouvez écrire du texte dans un fichier. Ces deux actions impliquent un flux de données. Ainsi, le concept de traitement d'un flux de données en tant que fichier n'est pas si exagéré.
Chaque instance d'un fichier ouvert associé à un processus se voit attribuer un numéro unique pour l'identifier. C'est ce qu'on appelle le descripteur de fichier. Chaque fois qu'une action doit être effectuée sur un fichier, le descripteur de fichier est utilisé pour identifier le fichier.
Ces valeurs sont toujours utilisées pour stdin, stdout et stderr :
- 0: stdin
- 1: stdout
- 2: stderr
Les appels système dup et dup2
dup
L'appel système dup()
crée une copie d'un descripteur de fichier.
- Il utilise le descripteur inutilisé portant le numéro le plus bas pour le nouveau descripteur.
- Si la copie est créée avec succès, les descripteurs de fichier d'origine et de copie peuvent être utilisés de manière interchangeable.
- Ils se réfèrent tous les deux au même descripteur de fichier ouvert et partagent donc les indicateurs de décalage de fichier et d'état de fichier.
dup2
L'appel système dup2()
est similaire à dup()
mais la différence fondamentale entre eux est qu'au lieu d'utiliser le descripteur de fichier inutilisé portant le numéro le plus bas, il utilise le numéro de descripteur spécifié par l'utilisateur.
Lors de l'appel de dup2 dans Rust, les paramètres donnés doivent être l'ancien descripteur de fichier et le nouveau.
Redirections
Quand vous voulez rediriger stdout
vers un fichier vous pouvez le faire en ouvrant un fichier à l'aide de l'appel système open()
, puis en dupliquant ce descripteur de fichier sur stdout
en utilisant dup2()
, de sorte que la sortie standard soit maintenant représentée par le fichier ouvert et non par la console.
use std::fs::File;
use std::io::{self, Write};
use std::os::unix::io::AsRawFd;
fn main() -> io::Result<()> {
// Open a file to redirect stdout
let file = File::open("test.txt")?;
// Get the raw file descriptor
let fd = file.as_raw_fd();
// Redirect stdout to the file
unsafe {
libc::dup2(fd, libc::STDOUT_FILENO);
}
// Anything printed to stdout will be redirected to the file
println!("Hello, redirected stdout!");
Ok(())
}
Exercises
- Lisez votre nom à partir du clavier en utilisant stdin. Imprimer le nom en utilisant stdout. N'utilisez pas le println!
- Imprimer le contenu d'un fichier reçu en tant qu'argument de ligne de commande sur stdout. N'utilisez pas le println!
- Lisez 3 nombres depuis le clavier en utilisant
stdin
. Écrivez le maximum de ces 3 nombres dans le fichier maximum.txt. - Copiez le contenu d'un fichier donné comme argument depuis la ligne de commande dans un fichier nommé
copy.txt
. - Ouvrez 2 instances du même fichier (ouvrez le fichier 2 fois). Lisez 10 octets de chaque instance et imprimez-les. Ouvrez une nouvelle instance du fichier et utilisez
dup()
pour faire une copie du descripteur de fichier de cette nouvelle instance. Lisez à partir des deux descripteurs de fichiers et voyez les différences entre la première situation et celle-ci. - Écrivez la date d'aujourd'hui par
redirection
de stdout dans un fichier appeléoutput.txt
en utilisant la fonction write_all. - Lisez 5 noms de filles à partir du clavier en utilisant stdin et ecrivez-les dans un fichier appelee
names.txt
en utilisant stdout. Executez encore une fois le programme et lisez 5 noms de garçons à partir du clavier. Il faut ajouter les noms de garçons aux noms des filles déjà existants dans names.txt, et non pas écraser le fichier!
Utilisez OpenOptions pour ajouter au fichier.