Quels sont les descripteurs de fichiers, expliqués en termes simples?

384
  1. Quelle serait une description plus simplifiée des descripteurs de fichiers par rapport à Wikipédia? Pourquoi sont-ils nécessaires? Prenons l'exemple des processus shell et comment cela s'applique-t-il?

  2. Une table de processus contient-elle plusieurs descripteurs de fichier? Si oui, pourquoi?

Nishant
la source
3
Qu'en est-il des concepts de stdin stdout stderr, etc.? J'ai une instance telle que le processus de navigateur ouvert et il a ouvert des fichiers temporaires pour afficher mon html. Le processus utilise le même fd pour lire / écrire? De plus, la table de processus ....... elle a des entrées comme fd0 pointer fd1 pointer fd2 pointer ..... cela signifie-t-il que tous ces fichiers sont en RAM? Sinon, pourquoi les pointeurs?
Nishant
43
Lorsque vous ouvrez un fichier, le système d'exploitation crée un flux vers ce fichier et connectez ce flux au fichier ouvert, le descripteur représente en fait ce flux. De même, certains flux par défaut sont créés par le système d'exploitation. Ces flux sont connectés à votre terminal au lieu de fichiers. Donc, lorsque vous écrivez quelque chose dans le terminal, il va au flux stdin et au système d'exploitation. Et lorsque vous écrivez la commande "ls" sur le terminal, le système d'exploitation écrit la sortie dans le flux stdout. Le flux stdout est connecté à votre terminal moniteur afin que vous puissiez voir la sortie à cet endroit.
Tayyab
1
En ce qui concerne l'exemple du navigateur, il n'est pas nécessaire que le navigateur garde les fichiers ouverts. Cela dépend de l'implémentation du navigateur, mais dans la plupart des cas, le navigateur ouvre un fichier temporaire, écrit le fichier et ferme le fichier, il n'est donc pas nécessaire que le fichier soit ouvert même si la page Web est ouverte. Et le descripteur ne contient que les informations du fichier et ne conserve pas nécessairement le fichier en RAM. Lorsque vous lisez les données d'un descripteur, le système d'exploitation lit les données du disque dur. Les informations contenues dans le descripteur de fichier représentent simplement l'emplacement du fichier sur le disque dur, etc.
Tayyab
5
Le descripteur de fichier vers le fichier n'est pas un mappage un à un. Je pouvais ouvrir () le même fichier 4 fois et obtenir 4 descripteurs de fichiers différents. Chacun d'eux peut être utilisé (en fonction des drapeaux passés à l'open ()) pour la lecture, l'écriture ou les deux. Pour autant que le fichier soit en RAM ou sur disque - cela vous est caché par le noyau et ses différents caches. En fin de compte, quel est le cache correspondra à ce qui est sur le disque (pour l'écriture), et le noyau ne retournera pas sur le disque, pour la lecture, si les données sont déjà dans le cache.
Beano
7
Ceci est un bon article pour le comprendre facilement bottomupcs.com/file_descriptors.xhtml
Krishan Gopal

Réponses:

562

En termes simples, lorsque vous ouvrez un fichier, le système d'exploitation crée une entrée pour représenter ce fichier et stocker les informations sur ce fichier ouvert. Donc, s'il y a 100 fichiers ouverts dans votre système d'exploitation, il y aura 100 entrées dans le système d'exploitation (quelque part dans le noyau). Ces entrées sont représentées par des entiers comme (... 100, 101, 102 ....). Ce numéro d'entrée est le descripteur de fichier. Il s'agit donc simplement d'un nombre entier qui représente uniquement un fichier ouvert dans le système d'exploitation. Si votre processus ouvre 10 fichiers, votre table Process aura 10 entrées pour les descripteurs de fichiers.

De même, lorsque vous ouvrez un socket réseau, il est également représenté par un entier et il est appelé Socket Descriptor. J'espère que tu comprends.

Tayyab
la source
8
Aussi, c'est pourquoi vous pouvez manquer de descripteurs de fichiers, si vous ouvrez beaucoup de fichiers à la fois. Ce qui empêchera les systèmes * nix de fonctionner, car ils ouvrent des descripteurs en /procpermanence.
Spencer Rathbun
8
@ErbenMo: Non, ce n'est peut-être pas pareil. Lorsque vous ouvrez un fichier, le système d'exploitation attribue un FD disponible et lorsque vous le fermez, le système d'exploitation libère le FD et peut attribuer ce FD à un autre fichier ouvert par la suite. La façon dont son système d'exploitation suit les fichiers ouverts et cela n'a rien à voir avec un fichier spécifique.
Tayyab
49
" Il ne s'agit donc que d'un nombre entier qui représente uniquement un fichier ouvert dans le système d'exploitation. " C'est incorrect. Cet entier représente uniquement un fichier ouvert dans un processus . Le descripteur de fichier 0, par exemple, représentera un fichier ouvert dans un processus et un fichier ouvert complètement différent dans un autre processus.
Keith Thompson
15
@Tayyab: Je pense que vous vous trompez. Les descripteurs de fichier 0, 1 et 2 sont l'entrée standard, la sortie standard et l'erreur standard pour chaque processus en cours d'exécution. Un appel initial réussi à open()vous donnera le descripteur de fichier 3, même si un autre processus en cours d'exécution a un descripteur de fichier 3. Voir la définition POSIX deopen() : "La fonction open () retournera un descripteur de fichier pour le fichier nommé qui est le plus bas descripteur de fichier actuellement non ouvert pour ce processus . " (pas d'italique dans l'original).
Keith Thompson
17
@KeithThompson: Oui, vous avez raison. En fait, c'est à propos du niveau d'abstraction. En fait, deux tables sont conservées, la première étant par processus et la seconde à l'échelle du système. FD dans la table par processus (c'est-à-dire fdtable) n'est pas unique à l'échelle du système. Cependant, il est mappé à la table de v-nœuds contenant les entrées uniques à l'échelle du système. Ainsi, lorsque vous appelez les fonctions fopen () et fileno () pour vérifier le descripteur, vous pouvez obtenir le même numéro FD dans 2 processus différents car il renvoie l'index de fdtable qui est par processus. Merci de l'avoir soulevé !!
Tayyab
116

Un descripteur de fichier est un descripteur opaque utilisé dans l'interface entre l'espace utilisateur et le noyau pour identifier les ressources de fichier / socket. Par conséquent, lorsque vous utilisez open()ou socket()(appels système pour interfacer avec le noyau), vous recevez un descripteur de fichier, qui est un entier (il s'agit en fait d'un index dans la structure du processus u - mais ce n'est pas important). Par conséquent, si vous voulez une interface directe avec le noyau appelle, système à l' aide de read(), write(),close() etc. la poignée que vous utilisez est un descripteur de fichier.

Il existe une couche d'abstraction superposée sur les appels système, qui est l' stdiointerface. Cela fournit plus de fonctionnalités / fonctionnalités que les appels système de base. Pour cette interface, le handle opaque que vous obtenez est un FILE*, qui est renvoyé par l' fopen()appel. Il y a beaucoup de nombreuses fonctions qui utilisent l' stdiointerface de fprintf(), fscanf(), fclose()qui sont là pour vous rendre la vie plus facile. En C, stdin, stdout, et stderrsont FILE*, dans laquelle la carte UNIX respectivement aux descripteurs de fichiers 0, 1et 2.

Beano
la source
6
Je pense personnellement que cette réponse est meilleure que celle indiquée comme réponse. A voté.
Tarik
101

Écoutez-le de la bouche du cheval: APUE (Richard Stevens).
Pour le noyau, tous les fichiers ouverts sont référencés par des descripteurs de fichiers. Un descripteur de fichier est un nombre non négatif.

Lorsque nous ouvrons un fichier existant ou créons un nouveau fichier, le noyau renvoie un descripteur de fichier au processus. Le noyau conserve une table de tous les descripteurs de fichiers ouverts, qui sont en cours d'utilisation. L'attribution des descripteurs de fichiers est généralement séquentielle et ils sont attribués au fichier en tant que prochain descripteur de fichiers gratuit à partir du pool de descripteurs de fichiers gratuits. Lorsque nous fermons le fichier, le descripteur de fichier est libéré et est disponible pour une attribution ultérieure.
Voir cette image pour plus de détails:

Deux processus

Lorsque nous voulons lire ou écrire un fichier, nous identifions le fichier avec le descripteur de fichier qui a été renvoyé par l' appel de fonction open () ou create () , et nous l'utilisons comme argument pour lire () ou écrire () .
C'est par convention que les shells UNIX System associent le descripteur de fichier 0 à l'entrée standard d'un processus, le descripteur de fichier 1 à la sortie standard et le descripteur de fichier 2 à l'erreur standard .
Le descripteur de fichier va de 0 à OPEN_MAX. La valeur maximale du descripteur de fichier peut être obtenue avec ulimit -n. Pour plus d'informations, consultez le 3ème chapitre du livre APUE.

Shekhar Kumar
la source
1
Puisque 0, 1, 2 sont associés à "stdin", "stdout" et "stderr" d'un processus, pouvons-nous utiliser ces descripteurs en même temps pour différents processus?
Tarik
@Tarik: les descripteurs de fichiers sont par processus. Pour voir cela, téléchargez osquery et exécutez-le osqueryi <<< echo '.all process_open_files'dans un shell bash.
Ben Creasy
29

D'autres réponses ont ajouté d'excellentes choses. J'ajouterai juste mes 2 cents.

Selon Wikipedia, nous savons avec certitude: un descripteur de fichier est un entier non négatif. Je pense que la chose la plus importante qui manque est de dire:

Les descripteurs de fichiers sont liés à un ID de processus.

Nous savons que les descripteurs de fichiers les plus connus sont 0, 1 et 2. 0 correspond à STDIN, 1 à STDOUTet 2 à STDERR.

Prenons l'exemple des processus shell et comment cela s'applique-t-il?

Découvrez ce code

#>sleep 1000 &
[12] 14726

Nous avons créé un processus avec l'ID 14726 (PID). En utilisant le lsof -p 14726nous pouvons obtenir des choses comme ceci:

COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
sleep   14726 root  cwd    DIR    8,1     4096 1201140 /home/x
sleep   14726 root  rtd    DIR    8,1     4096       2 /
sleep   14726 root  txt    REG    8,1    35000  786587 /bin/sleep
sleep   14726 root  mem    REG    8,1 11864720 1186503 /usr/lib/locale/locale-archive
sleep   14726 root  mem    REG    8,1  2030544  137184 /lib/x86_64-linux-gnu/libc-2.27.so
sleep   14726 root  mem    REG    8,1   170960  137156 /lib/x86_64-linux-gnu/ld-2.27.so
sleep   14726 root    0u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    1u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    2u   CHR  136,6      0t0       9 /dev/pts/6

La 4ème colonne FD et la toute prochaine colonne TYPE correspondent au descripteur de fichier et au type de descripteur de fichier.

Certaines des valeurs pour le FD peuvent être:

cwd – Current Working Directory
txt – Text file
mem – Memory mapped file
mmap – Memory mapped device

Mais le vrai descripteur de fichier est sous:

NUMBER – Represent the actual file descriptor. 

Le caractère après le chiffre, c'est-à-dire "1u", représente le mode dans lequel le fichier est ouvert. r pour lire, w pour écrire, u pour lire et écrire.

TYPE spécifie le type du fichier. Certaines des valeurs des TYPE sont:

REG – Regular File
DIR – Directory
FIFO – First In First Out

Mais tous les descripteurs de fichiers sont CHR - Fichier spécial de caractères (ou fichier de périphérique de caractères)

Maintenant, nous pouvons identifier les descripteurs de fichiers pour STDIN, STDOUTet STDERRfacile avec lsof -p PID, ou nous pouvons voir la même chose si nous ls /proc/PID/fd.

Notez également que la table de descripteurs de fichiers dont le noyau assure le suivi n'est pas la même que la table de fichiers ou la table d'inodes. Celles-ci sont distinctes, comme l'expliquent certaines autres réponses.

tableau fd

Vous pouvez vous demander où sont physiquement ces descripteurs de fichiers et ce qui est stocké /dev/pts/6par exemple

sleep   14726 root    0u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    1u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    2u   CHR  136,6      0t0       9 /dev/pts/6

Eh bien, /dev/pts/6vit purement dans la mémoire. Ce ne sont pas des fichiers normaux, mais des fichiers appelés périphériques de caractères . Vous pouvez vérifier cela avec: ls -l /dev/pts/6et ils commenceront par c, dans mon cas crw--w----.

Juste pour rappeler la plupart des Linux comme OS, définissez sept types de fichiers:

  • Fichiers réguliers
  • Répertoires
  • Fichiers de périphérique de caractères
  • Bloquer les fichiers de l'appareil
  • Prises de domaine local
  • Tubes nommés (FIFO) et
  • Liens symboliques
prosti
la source
1
Merci. En effet il est important de préciser que c'est par process! Cela aide à mieux visualiser les choses.
Nishant
1
Les types de fichiers définis par OS, que vous avez mentionnés dans votre réponse, aident vraiment à comprendre les fichiers à un niveau inférieur.
Rohan Bhale
20

Plus de points concernant File Descriptor:

  1. File Descriptors(FD) sont des entiers non négatifs (0, 1, 2, ...)associés aux fichiers ouverts.

  2. 0, 1, 2sont des FD standard qui correspondent à STDIN_FILENO, STDOUT_FILENOet STDERR_FILENO(définis dans unistd.h) ouverts par défaut au nom du shell au démarrage du programme.

  3. Les FD sont alloués dans l'ordre séquentiel, ce qui signifie la valeur entière non allouée la plus basse possible.

  4. Les FD pour un processus particulier peuvent être vus dans /proc/$pid/fd(sur les systèmes basés sur Unix).

Sandeep_black
la source
16

En plus des autres réponses, unix considère tout comme un système de fichiers. Votre clavier est un fichier qui est en lecture seule du point de vue du noyau. L'écran est un fichier en écriture seule. De même, les dossiers, les périphériques d'entrée-sortie, etc. sont également considérés comme des fichiers. Chaque fois qu'un fichier est ouvert, par exemple lorsque les pilotes de périphérique [pour les fichiers de périphérique] demandent un open (), ou lorsqu'un processus ouvre un fichier utilisateur, le noyau alloue un descripteur de fichier, un entier qui spécifie l'accès à ce fichier tel qu'il soit en lecture seule , écrivez seulement etc. [pour référence: https://en.wikipedia.org/wiki/Everything_is_a_file ]

Balu
la source
Les descripteurs de fichiers peuvent également faire référence à des éléments qui n'existent pas dans le système de fichiers, comme les canaux anonymes et les sockets réseau.
kbolino
12

Descripteurs de fichiers (FD):

  • Sous Linux / Unix , tout est un fichier. Les fichiers ordinaires, les répertoires et même les périphériques sont des fichiers. Chaque fichier a un numéro associé appelé descripteur de fichier (FD).
  • Votre écran possède également un descripteur de fichier. Lorsqu'un programme est exécuté, la sortie est envoyée au descripteur de fichier de l'écran et vous voyez la sortie du programme sur votre moniteur. Si la sortie est envoyée au descripteur de fichier de l'imprimante, la sortie du programme aurait été imprimée.

    Redirection d'erreur:
    chaque fois que vous exécutez un programme / commande sur le terminal, 3 fichiers sont toujours ouverts
    1. entrée standard
    2. sortie standard
    3. erreur standard.

    Ces fichiers sont toujours présents chaque fois qu'un programme est exécuté. Comme expliqué précédemment, un descripteur de fichier est associé à chacun de ces fichiers.
    Fichier                                        Descripteur de fichier
    Entrée standard STDIN 0
    Sortie standard STDOUT 1
    Erreur standard STDERR 2

  • Par exemple, lors de la recherche de fichiers, on obtient généralement des erreurs d'autorisation refusée ou d'autres types d'erreurs. Ces erreurs peuvent être enregistrées dans un fichier particulier.
    Exemple 1

$ ls mydir 2> fichier_erreurs.txt

Le descripteur de fichier pour l'erreur standard est 2.
S'il n'y a aucun répertoire nommé mydir, la sortie de la commande sera enregistrée dans le fichier errorfile.txt.
En utilisant "2>", nous redirigeons la sortie d'erreur vers un fichier nommé "errorfile". txt "
Ainsi, la sortie du programme n'est pas encombrée d'erreurs.

J'espère que vous avez obtenu votre réponse.

Abhishek Kamal
la source
5

Tout système d'exploitation a des processus (p) en cours d'exécution, par exemple p1, p2, p3 et ainsi de suite. Chaque processus utilise généralement des fichiers en continu.

Chaque processus est composé d'une arborescence de processus (ou d'une table de processus, dans un autre phrasé).

Habituellement, les systèmes d'exploitation représentent chaque fichier de chaque processus par un numéro (c'est-à-dire dans chaque arbre / table de processus).

Le premier fichier utilisé dans le processus est file0 , le deuxième est file1 , le troisième est file2 , etc.

Un tel nombre est un descripteur de fichier.

Les descripteurs de fichiers sont généralement des entiers (0, 1, 2 et non 0,5, 1,5, 2,5).

Étant donné que nous décrivons souvent les processus comme des "tables de processus", et étant donné que les tables ont des lignes (entrées), nous pouvons dire que la cellule de descripteur de fichier dans chaque entrée, utilise pour représenter l'entrée entière.

De la même manière, lorsque vous ouvrez un socket réseau, il a un descripteur de socket.

Dans certains systèmes d'exploitation, vous pouvez manquer de descripteurs de fichiers, mais ce cas est extrêmement rare, et l'utilisateur moyen de l'ordinateur ne devrait pas s'en inquiéter.

Les descripteurs de fichiers peuvent être globaux (le processus A commence par exemple 0 et se termine par 1; le processus B commence par 2 et se termine par 3) et ainsi de suite, mais pour autant que je sache, généralement dans les systèmes d'exploitation modernes, fichier les descripteurs ne sont pas globaux et sont en fait spécifiques au processus (le processus A commence par exemple 0 et se termine par 5, tandis que le processus B commence par 0 et se termine par 10).


la source
En savoir plus sur les FD sous Linux ici: unix.stackexchange.com/questions/358022/…
1
bonne réponse :)
humble_wolf
5

Descripteurs de fichiers

  • Pour le noyau, tous les fichiers ouverts sont référencés par des descripteurs de fichiers.
  • Un descripteur de fichier est un entier non négatif.
  • Lorsque nous ouvrons un fichier existant ou créons un nouveau fichier, le noyau renvoie un descripteur de fichier à un processus.
  • Lorsque nous voulons lire ou écrire sur un fichier, nous identifions le fichier avec un descripteur de fichier qui a été réaccordé par open ou create, comme argument à lire ou à écrire.
  • Chaque processus UNIX possède 20 descripteurs de fichiers et sa suppression, numérotée de 0 à 19, mais il a été étendu à 63 par de nombreux systèmes.
  • Les trois premiers sont déjà ouverts au début du processus 0: l'entrée standard 1: la sortie standard 2: la sortie d'erreur standard
  • Lorsque le processus parent bifurque un processus, le processus enfant hérite des descripteurs de fichier du parent
Mahendra suthar
la source
1

Ajout à des réponses surtout simplifiées.
Si vous travaillez avec des fichiers dans le script bash, il est préférable d'utiliser un descripteur de fichier.
Par exemple: -
Vous souhaitez lire et écrire depuis / vers le fichier "test.txt".
Utilisez le descripteur de fichier comme indiqué ci-dessous

FILE=$1 # give the name of file in the command line
exec 5<>$FILE # '5' here act as the file descriptor
# Reading from the file line by line using file descriptor
while read LINE; do
    echo "$LINE"
done <&5

# Writing to the file using descriptor
echo "Adding the date: `date`" >&5 
exec 5<&- # Closing a file descriptor
sumitsinghdeode
la source
-5

Les descripteurs de fichiers sont les descripteurs d'un fichier. Ils donnent des liens vers un fichier. Avec leur aide, nous pouvons lire, écrire et ouvrir un fichier.

Motimahal
la source