¿Cómo es un directorio un "tipo especial de archivo"?

Respuestas:

19

Muchas entidades en los sistemas operativos de estilo * nix (y otros) se consideran archivos, o tienen un aspecto definitorio similar a un archivo, a pesar de que no son necesariamente una secuencia de bytes almacenados en un sistema de archivos. Exactamente cómo se implementan los directorios depende del tipo de sistema de archivos, pero en general lo que contienen, considerado como una lista, es una secuencia de bytes almacenados, por lo que en ese sentido no son tan especiales.

Una forma de definir qué es un "archivo" en un contexto * nix es que es algo que tiene un descriptor de archivo asociado. Según el artículo de Wikipedia, un descriptor de archivo

es un indicador abstracto que se usa para acceder a un archivo u otro recurso de entrada / salida , como una tubería o una conexión de red ...

En otras palabras, se refieren a varios tipos de recursos desde / hacia los cuales se puede leer / escribir una secuencia de bytes, aunque el origen / destino de esa secuencia no está especificado. Dicho de otra manera, el "dónde" del recurso podría ser cualquier cosa. Lo que lo define es que es un conducto de información. Esto es parte de por qué a veces se dice que en unix "todo es un archivo". No debe tomar eso completamente literalmente, pero vale la pena considerarlo seriamente. En el caso de un directorio, esta información se refiere a lo que está en el directorio y, en un nivel inferior de implementación, cómo encontrarlo dentro del sistema de archivos.

Los directorios son algo especiales en este sentido porque en el código C nativo no están aparentemente asociados con un descriptor de archivo; la API POSIX utiliza un tipo especial de referencia de flujo, DIR*. Sin embargo, este tipo tiene un descriptor subyacente que se puede recuperar . Los descriptores son administrados por el núcleo y acceder a ellos siempre involucra llamadas del sistema, por lo tanto, otro aspecto de lo que es un descriptor es que es un conducto controlado por el núcleo del sistema operativo. Tienen números únicos (por proceso) que comienzan con 0, que generalmente es el descriptor de la secuencia de entrada estándar .

encerrada dorada
fuente
2
POSIX.1-2008 añadió un montón de llamadas al sistema ( openat, fstatat, etc), que utilizan descriptores de archivos que se refieren a los directorios.
zwol
2
Aún más interesante, puede hacer fsync()un directorio de solo lectura (!) Fd, y tiene un efecto bien definido (específicamente, sincroniza la creación / cambio de nombre / eliminación de archivos en el directorio dado al disco, un paso teóricamente necesario en la "escritura" a un archivo temporal y renómbrelo sobre el "modismo" original.
Kevin
13

En la forma de hacer las cosas de Unix: todo es un archivo.

Un directorio es uno (de muchos) tipos de archivos especiales. No contiene datos. En su lugar, contiene punteros a todos los archivos contenidos en el directorio.

Otros tipos de archivos especiales:

  • campo de golf
  • enchufes
  • dispositivos

Pero debido a que se consideran "archivos", puede lsmodificarlos y cambiarles el nombre, moverlos y, según el tipo de archivo especial, enviar datos a ellos o desde ellos.

hymie
fuente
1
Y esto hace la vida mucho más fácil, porque no tienes que hacer algo diferente solo porque es un directorio. Esto se aplica a la escritura de programas, así como a las operaciones desde la línea de comandos (o GUI).
gbarry
1
Un directorio contiene datos: los datos que describen los archivos contenidos en el directorio. Es perfectamente posible acceder a un directorio (aunque quizás no con una llamada abierta estándar) y leer esos datos usted mismo, aunque (como señala Bruce Ediger en su respuesta) los datos no son muy útiles a menos que conozca el formato.
jamesqf
11

Mi respuesta es una mera reminiscencia, pero en 199x Unixes antiguos, de los cuales había muchos, los directorios eran archivos, simplemente marcados como "directorio" en algún lugar del inodo en el disco.

Puede abrir un directorio con algo como open(".", O_RDONLY)y recuperar un descriptor de archivo utilizable. Puede analizar el contenido si busca /usr/includey encuentra la definición correcta de C struct. Sé que hice esto para los sistemas SunOS 4.1.x, el sistema de archivos EFS de SGI y las estaciones de trabajo Mips-CPU de DEC para un sistema de archivos, probablemente BSD4.2 FFS.

Esa fue una mala experiencia. La estandarización en una capa de sistema de archivos virtual es algo bueno para la portabilidad, incluso si los directorios ya no son archivos estrictos. Las capas VFS nos permiten experimentar con sistemas de archivos donde los directorios no son archivos, como ReiserFS o NFS.

Bruce Ediger
fuente
1
Todavía puede abrir un directorio y leerlo como un archivo en algunas variantes de Unix hoy, por ejemplo, todavía es posible en FreeBSD 10.1. (Can ≠ should)
Gilles 'SO- deja de ser malvado'
@Gilles Creo que sería muy lógico si un directorio copiado por dd fuera esencialmente un equivalente de cp --link dir1/* dir2, aunque no estoy seguro de su usabilidad.
Peter dice reinstalar a Mónica
3

Un directorio es especial porque tiene la 'd' en su modo, diciéndole al sistema de archivos que debe interpretar su contenido como una lista de otros archivos contenidos dentro del directorio, en lugar de un archivo normal que es solo una secuencia de bytes leído por la aplicación Eso es todo.

psusi
fuente
Las cosas no son tan simples con todos los sistemas de archivos, por ejemplo, en el HFS + de Apple solo hay un gran árbol B + que contiene todos los nombres de ruta, si mal no recuerdo, pero esta observación es perfecta para los sistemas de archivos Unix hasta e incluyendo ffs de BSD, que es probablemente lo que los autores del tutorial citado estaban pensando.
zwol
2

Los directorios son archivos porque los sistemas Linux emplean i universal / o modelo . En el modelo, todo en el sistema es un archivo y se puede acceder con las mismas llamadas al sistema y varios comandos.

Son de tipo especial porque sus nodos-i tienen la marca para el tipo de archivo y tienen una estructura especial de ser una tabla de nombres de archivo y enlaces a otros nodos-i. Estos pares de enlaces de nombre de archivo, también conocidos como "enlaces duros", en el nodo i de un directorio enumeran los archivos "dentro" del directorio.

Los directorios son solo para organizar archivos. Cuando un archivo se "mueve" de un directorio a otro, el archivo en sí no se reubica en el disco. Es solo que una entrada en un directorio i-nodos se elimina y se escribe en otro directorio i-nodo.

Henri Kynsilehto
fuente
-3

La respuesta aceptada no es completamente correcta. en sistemas POSIX, "Inodes" apunta a archivos y directorios. Los descriptores de archivos son exclusivos de un proceso y no en un sistema. Sin embargo, los inodos son únicos, aunque más de un inodo puede apuntar a un solo archivo. Habría comentado sobre la respuesta aceptada pero no pudo debido a la restricción de representantes.

almiar
fuente
2
No, solo 1 inodo puede apuntar al mismo archivo. Aunque el mismo inodo puede existir simultáneamente en múltiples directorios (o en múltiples nombres). Un registro fácil: ls -l >test.txt;ln -vf test.txt test2.txt;ls -li test.txt test2.txt. Entonces verá que los enlaces duros tienen el mismo número de inodo.
Peter dice reinstalar a Mónica
@peterh Los descriptores de archivo son únicos para un proceso. ¿puedes explicar?
alamin
1
@ Md.AlaminMahamud No es cierto, si un proceso fork()s, su proceso hijo tendrá (excepto alguna circunstancia especial, es decir, una O_CLOEXECbandera) exactamente las mismas entidades descriptoras de archivos que tenía el proceso original. Otro ejemplo: los procesos secundarios apache están listen()en el mismo descriptor de archivo de socket. Pero esta respuesta no se trata de los descriptores de archivo, que son una estructura de datos interna del núcleo y existen solo en la memoria del núcleo. Esta respuesta ( falsa ) trata sobre las entradas de directorio y los inodos, estas son entidades en disco (es decir, son bytes físicos en el disco duro).
Peter dice reinstalar a Mónica el
1
@ Md.AlaminMahamud Bueno, ahora no estoy muy seguro, por ejemplo, si fork()sucede y luego el niño procesa seek()s o close()s, no afectará el descriptor de archivo del padre. Así que ahora estoy pensando que los descriptores de archivos son solo estructuras parcialmente privadas de proceso. Pero esta pregunta no se trata de ellos, se trata de los dirents / inodes y te estoy comentando una respuesta completamente falsa a esta pregunta.
Peter dice reinstalar a Mónica el