¿Cuál es el concepto de crear un archivo con cero bytes en Linux?

32

Si hago lo siguiente:

touch /tmp/test

y luego realizar

ls -la /tmp/

Pude ver el testarchivo con 0 Bytes en el directorio.

Pero, ¿cómo maneja el sistema operativo un concepto de 0 bytes ? Si lo pongo en términos simples:

0 Bytes no es memoria en absoluto, por lo tanto, no se crea nada.

La creación de un archivo, debe o debe al menos requerir cierta memoria, ¿verdad?

Shan-Desai
fuente

Respuestas:

63

Un archivo es (aproximadamente) tres cosas separadas:

  • Un "inodo", una estructura de metadatos que realiza un seguimiento de quién posee el archivo, los permisos y una lista de bloques en el disco que realmente contienen los datos.
  • Una o más entradas de directorio (los nombres de archivo) que apuntan a ese inodo
  • Los bloques de datos reales en sí mismos

Cuando crea un archivo vacío, crea solo el inodo y una entrada de directorio que apunta a ese inodo. Lo mismo para archivos dispersos ( dd if=/dev/null of=sparse_file bs=10M seek=1).

Cuando crea enlaces duros a un archivo existente, simplemente crea entradas de directorio adicionales que apuntan al mismo inodo.

He simplificado las cosas aquí, pero entiendes la idea.

xhienne
fuente
2
Bien dicho. mientras promociona un pequeño enigma con su párrafo de "enlaces duros": si uno crea un enlace duro a un archivo vacío, que usted afirma que no tiene una lista de bloques, ¿cómo puede ese enlace duro apuntar a la (misma) lista de bloques que no existen
Theophrastus
44
@Theophrastus Buen punto. He hecho posible simplificar las cosas. En realidad, entre la lista de bloques y las entradas de directorio, hay metadatos pertenecientes al archivo (referido por un número de inodo) y que contienen atributos de archivo (propietario, permisos, ...) y atributos extendidos. La lista de bloques está ahí. Por lo tanto, todas las entradas del directorio no apuntan directamente a la lista de bloques (la forma FAT), sino a los metadatos.
xhienne
66
Debería haber tres cosas separadas: una lista de bloques que contienen datos; los propios bloques ; y una entrada de directorio (o entradas) que apunta a la lista de bloques.
Comodín el
@Wildcard He enviado una edición para hacer tres cosas, y me referí al inodo por su nombre. Tanto el inodo como los directorios son metadatos; pero son diferentes tipos de metadatos. Un archivo siempre tiene un inodo y al menos una entrada de directorio. Ese inodo puede incluir una lista vacía de bloques de datos.
Monty Harder
1
@Wildcard Incluso si es un principiante, es importante comprender la diferencia entre un inodo y un directorio. Cuando alguien cambia los permisos / propiedad de "un nombre de directorio" y piensa que otros enlaces al mismo inodo retendrán los permisos / propiedad antiguos, algo muy malo podría suceder. No tenemos que profundizar en los detalles de cómo los inodes hacen referencia a bloques directos, bloques indirectos, bloques doble y triplemente indirectos para obtener una lista de bloques. O que una lista puede estar vacía.
Monty Harder
24

touchcreará un inodo y / ls -io statmostrará información sobre el inodo:

$ touch test
$ ls -i test
28971114 test
$ stat test
  File: ‘test’
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: fc01h/64513d    Inode: 28971114    Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/1000)   Gid: ( 1000/1000)
Access: 2017-03-28 17:38:07.221131925 +0200
Modify: 2017-03-28 17:38:07.221131925 +0200
Change: 2017-03-28 17:38:07.221131925 +0200
 Birth: -

Observe que testusa 0 bloques. Para almacenar los datos mostrados, el inodo usa algunos bytes. Esos bytes se almacenan en la tabla de inodo. Mire la página ext2 para ver un ejemplo de una estructura de inodo .

ctx
fuente
19

ls(o bueno, la stat(2)llamada al sistema) le indica el tamaño del contenido del archivo. La cantidad de espacio que necesita el sistema de archivos para la contabilidad no es parte de eso, y como detalle de implementación, no es algo que a los programas en general les deba importar o incluso saber. Hacer visibles los detalles de implementación haría que la abstracción del sistema de archivos fuera menos útil.

ilkkachu
fuente
9

El archivo, en sí mismo, no ocupa ningún espacio, pero el sistema de archivos sí lo hace, almacenando el nombre de archivo, la ubicación, los derechos de acceso y similares.

Patrick Bucher
fuente
44
Si observa el espacio ocupado por la entrada del directorio, si tiene un directorio que contiene mil archivos que tienen un tamaño de 0 bytes, el directorio será más grande que una entrada de directorio que tenga solo 2 archivos enormes.
Mark Stewart
2
accesorios para mencionar que un archivo es un concepto abstracto que no está estrechamente vinculado con su representación física en, por ejemplo, un disco.
Florian Castellane
5

Respuesta simple: porque se define de esa manera.

Respuesta más larga: se define de esa manera porque algunas operaciones son conceptualmente más simples:

  • Si un archivo contiene 20 letras "A" y elimina todas las "A", el archivo se acortará 20 bytes. La misma operación en un archivo que consistía solo en "AAAAAAAAAAAAAAAAAAAA" tendría que tratar con el caso especial de un archivo desaparecido.
  • Más prácticamente, la eliminación de la última línea de un archivo de texto debería estar en mayúsculas especiales.
  • Los editores de texto que regularmente hacen una copia de seguridad necesitarían un código de caso especial para lidiar con la situación de que el usuario podría eliminar la última línea, ir a almorzar, luego regresar y agregar otra línea. Surgen complicaciones adicionales si otros usuarios crean un archivo con ese nombre mientras tanto.

Puede hacer más cosas: * Los archivos de registro de errores tienden a crearse vacíos, para llenarse solo si ocurre un error. * Para saber cuántos errores ocurrieron, cuente el número de líneas en los archivos de registro. Si el archivo de registro está vacío, el número de errores es cero, lo que tiene mucho sentido. * A veces ve archivos donde todo el texto relevante está en el nombre del archivo, por ejemplo this-is-the-logging-directory. Esto evita que los administradores ansiosos eliminen directorios vacíos después de la instalación, y también evita errores en los que un programa o un usuario crean accidentalmente un archivo donde el programa desea ver un directorio más tarde. El gitprograma (y otros) tienden a ignorar los directorios vacíos, y si un proyecto / administrador / usuario quiere tener un registro de que el directorio existe aunque no tenga contenido útil (todavía), puede ver un archivo vacío llamadoemptyo empty.directory.

Ninguna operación se vuelve más complicada:

  • Concatenación de archivos: esto es solo un no-op con un archivo vacío.
  • Búsqueda de una cadena en un archivo: esto está cubierto por el caso estándar de "si el archivo es más corto que el término de búsqueda, no puede contener el término de búsqueda".
  • Lectura del archivo: los programas deben lidiar con presionar el final del archivo antes de obtener lo que esperaban, por lo que nuevamente el caso de un archivo de longitud cero no implica pensar más para el programador: simplemente presionará el final de -archivo desde el principio.

En el caso de los archivos, el aspecto "hay un archivo grabado en alguna parte" (inodo y / o nombre del archivo) se suma a las consideraciones anteriores, pero los sistemas de archivos no harían eso si los archivos vacíos fueran inútiles.

En general, todas las razones anteriores, excepto las relacionadas con los nombres de archivo, se aplican a las secuencias. Lo más notable para las cadenas, que son secuencias de caracteres: las cadenas de longitud cero son comunes dentro de los programas. Las cadenas generalmente no se permiten a nivel de usuario si no tienen sentido: un nombre de archivo es una cadena, y la mayoría de los sistemas de archivos no permiten una cadena vacía como nombre de archivo; internamente, al crear nombres de archivo a partir de fragmentos, el programa puede tener una cadena vacía como uno de los fragmentos.

forjador de herramientas
fuente
1

Usando la analogía más simple:

Comparemos un archivo con, digamos, un vaso de agua.

'touch / tmp / test' es muy parecido a crear un vaso vacío, sin agua. El vaso está vacío, por lo que su tamaño es cero. Pero el vidrio existe.

En el lenguaje del sistema de archivos, el vidrio son los metadatos, mientras que el contenido del vidrio son los datos. Los metadatos contienen todo tipo de cosas como se menciona en las publicaciones anteriores.

Los archivos de tamaño cero pueden ser útiles. Un ejemplo es usarlos como una ruta de exploración, donde su mera existencia se puede usar para indicar algún tipo de estado (es decir, si el archivo existe: entonces haga algo; si no: ignore).

El Stepherino
fuente
0

Piénselo de esta manera: digamos que un programa está rastreando consultas SQL enviadas a su servidor. El programa quiere indicar que está registrando solicitudes en un archivo de texto sin formato, pero aún no se han registrado solicitudes. ¿Cómo debería ser eso? Yo diría que debería ser un archivo de tamaño cero en /var/log/acme-sql-server/queries.log. De esa manera, podría averiguar cuándo comenzó el registro (el tiempo de creación del archivo), cuándo se actualizó por última vez (es decir, cuándo se creó), cuántas consultas se registraron (número de nuevas líneas en el archivo = 0) y quién está haciendo el registro (Acme SQL Server). Para casos como este, es útil tener el concepto de un archivo vacío que, sin embargo, existe en una ubicación particular.

Gaurav
fuente