¿Qué son los descriptores de archivos, explicados en términos simples?

Resuelto Nishant asked hace 13 años • 13 respuestas
  1. ¿Cuál sería una descripción más simplificada de los descriptores de archivos en comparación con la de Wikipedia? ¿Por qué son necesarios? Digamos, tomemos los procesos de Shell como ejemplo y ¿cómo se aplican?

  2. ¿Una tabla de procesos contiene más de un descriptor de archivo? ¿Si es así por qué?

Nishant avatar Mar 10 '11 14:03 Nishant
Aceptado

En palabras simples, cuando abre un archivo, el sistema operativo crea una entrada para representar ese archivo y almacenar la información sobre ese archivo abierto. Entonces, si hay 100 archivos abiertos en su sistema operativo, habrá 100 entradas en el sistema operativo (en algún lugar del kernel). Estas entradas están representadas por números enteros como (...100, 101, 102....). Este número de entrada es el descriptor del archivo. Por lo tanto, es solo un número entero que representa de forma única un archivo abierto para el proceso. Si su proceso abre 10 archivos, entonces su tabla de Proceso tendrá 10 entradas para descriptores de archivos.

De manera similar, cuando abre un socket de red, también se representa mediante un número entero y se llama Socket Descriptor. Espero que entiendas.

Tayyab avatar Mar 10 '2011 07:03 Tayyab

Un descriptor de archivo es un identificador opaco que se utiliza en la interfaz entre el usuario y el espacio del kernel para identificar recursos de archivos/sockets. Por lo tanto, cuando usa open()o socket()(llamadas al sistema para interactuar con el kernel), se le proporciona un descriptor de archivo, que es un número entero (en realidad es un índice de la estructura u del proceso, pero eso no es importante). Por lo tanto, si desea interactuar directamente con el kernel, utilizando llamadas al sistema a read(), etc. write(), close()el identificador que utiliza es un descriptor de archivo.

Hay una capa de abstracción superpuesta a las llamadas al sistema, que es la stdiointerfaz. Esto proporciona más funcionalidades/características que las llamadas básicas al sistema. Para esta interfaz, el identificador opaco que obtiene es a FILE*, que devuelve la fopen()llamada. Hay muchas funciones que utilizan la stdiointerfaz fprintf(), fscanf(), fclose(), que están ahí para hacerle la vida más fácil. En C, stdin, stdouty stderrson FILE*, que en UNIX se asignan respectivamente a descriptores de archivos 0, 1y 2.

Beano avatar Mar 10 '2011 09:03 Beano

Escúchalo desde la Boca del Caballo: APUE (Richard Stevens).
Para el kernel, todos los archivos abiertos se denominan descriptores de archivos. Un descriptor de archivo es un número no negativo.

Cuando abrimos un archivo existente o creamos un archivo nuevo, el kernel devuelve un descriptor de archivo al proceso. El kernel mantiene una tabla de todos los descriptores de archivos abiertos que están en uso. La asignación de descriptores de archivos es generalmente secuencial y se asignan al archivo como el siguiente descriptor de archivo libre del conjunto de descriptores de archivos libres. Cuando cerramos el archivo, el descriptor del archivo se libera y está disponible para su posterior asignación.
Vea esta imagen para más detalles:

Dos procesos

Cuando queremos leer o escribir un archivo, identificamos el archivo con el descriptor de archivo que fue devuelto por la llamada a la función open() o create() , y lo usamos como argumento para read() o write() .
Es por convención que los shells del sistema UNIX asocian el descriptor de archivo 0 con la entrada estándar de un proceso, el descriptor de archivo 1 con la salida estándar y el descriptor de archivo 2 con el error estándar .
El descriptor de archivo varía de 0 a OPEN_MAX. El valor máximo del descriptor de archivo se puede obtener con ulimit -n. Para obtener más información, consulte el capítulo 3 del Libro APUE.

Shekhar Kumar avatar Jul 19 '2013 08:07 Shekhar Kumar

Otras respuestas agregaron cosas geniales. Agregaré solo mis 2 centavos.

Según Wikipedia, lo sabemos con certeza: un descriptor de archivo es un número entero no negativo. Lo más importante que creo que falta sería decir:

Los descriptores de archivos están vinculados a un ID de proceso.

Sabemos que los descriptores de archivos más famosos son 0, 1 y 2. 0 corresponde a STDIN, 1 a STDOUTy 2 a STDERR.

Digamos, tomemos los procesos de Shell como ejemplo y ¿cómo se aplican?

Mira este código

#>sleep 1000 &
[12] 14726

Creamos un proceso con el id 14726 (PID). Usando lsof -p 14726podemos obtener cosas como esta:

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 cuarta columna FD y la siguiente columna TIPO corresponden al Descriptor de archivo y al tipo de Descriptor de archivo.

Algunos de los valores para el FD pueden ser:

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

Pero el descriptor de archivo real se encuentra en:

NUMBER – Represent the actual file descriptor. 

El carácter después del número, es decir, "1u", representa el modo en que se abre el archivo. r para leer, w para escribir, u para leer y escribir.

TIPO especifica el tipo de archivo. Algunos de los valores de TYPE son:

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

Pero todos los descriptores de archivos son CHR: archivo especial de caracteres (o archivo de dispositivo de caracteres)

Ahora podemos identificar los descriptores de archivos para y STDINfácilmente con , o podemos ver los mismos si .STDOUTSTDERRlsof -p PIDls /proc/PID/fd

Tenga en cuenta también que la tabla de descriptores de archivos de la que el kernel realiza un seguimiento no es la misma que la tabla de archivos o la tabla de inodos. Estos están separados, como explicaron algunas otras respuestas.

tabla fd

Quizás se pregunte dónde están físicamente estos descriptores de archivos y qué se almacena, /dev/pts/6por ejemplo, en

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

Bueno, /dev/pts/6vive puramente en la memoria. Estos no son archivos normales, sino los llamados archivos de dispositivo de caracteres . Puedes comprobar esto con: ls -l /dev/pts/6y comenzarán con c, en mi caso crw--w----.

Solo para recordar, la mayoría de los sistemas operativos tipo Linux definen siete tipos de archivos:

  • Archivos regulares
  • Directorios
  • Archivos de dispositivo de caracteres
  • Bloquear archivos del dispositivo
  • Conectores de dominio local
  • Tuberías con nombre (FIFO) y
  • Enlaces simbólicos
prosti avatar Sep 22 '2018 14:09 prosti