2010-12-27 9 views
6

En C cuando abrimos un archivo, ¿qué sucede? Como sé que el contenido del archivo no se carga en la memoria cuando abrimos un archivo. Simplemente establece el descriptor de archivo? Entonces, ¿qué es este descriptor de archivo? Y si el contenido del archivo no está cargado en la memoria, ¿cómo se abre un archivo?¿Qué está abriendo un archivo en C?

+2

Qué función está usando para abrir el archivo? – Thanatos

Respuesta

2

C no tiene primitivas para archivos E/S, todo depende de qué sistema operativo y qué bibliotecas está utilizando.

+2

'fopen' es la primitiva de C para E/S de archivos, y no depende del sistema operativo. (Aunque a menudo puede hacer llamadas a funciones específicas del sistema operativo para obtener más control.) – Thanatos

+1

Eso no es del todo correcto. 'fopen' es una función de biblioteca, no una primitiva. Además, dado que el acceso al archivo siempre lo realiza el SO, 'fopen' es realmente dependiente del sistema operativo. En un SO, 'fopen' podría leer adelante o escribir en el buffer, en otro podría no hacerlo. –

+0

no solo eso, sino que el formato de la cadena a la que se refiere fopen es completamente dependiente del sistema operativo. Tres elecciones populares usan/\ o: como – ddyer

1

Los descriptores de archivos son solo resúmenes. Todo está hecho en el sistema operativo.

0

Como ya se mencionó, es la funcionalidad del sistema operativo.

Pero para el archivo C de E/S muy probablemente necesita información sobre la función fopen.

Si usted lea la descripción de esa función, que dice:

Descripción:

Abre una secuencia.

fopen abre el archivo denominado por nombre de archivo y asocia una secuencia con . fopen devuelve un puntero para ser utilizado para identificar la secuencia en las siguientes operaciones .

Entonces, al completar con éxito fopen, simplemente devuelve un puntero a la secuencia recién abierta. Y devuelve NULL en caso de cualquier error.

6

Normalmente, si va a abrir un archivo con fopen o (en un sistema POSIX) open, la función, si tiene éxito, "abrir el archivo" - que simplemente le da un valor (un FILE * o un int) para usar en futuras llamadas a una función de lectura.

Bajo el capó, el sistema operativo podría leer algunos o todos los archivos, es posible que no. Debe llamar a alguna función para solicitar que los datos se lean de todos modos, y si no lo ha hecho cuando llame al fread/fgets/read/etc ... entonces lo hará en ese momento.

Un "descriptor de archivo" generalmente se refiere al número entero devuelto por open en sistemas POSIX. Se usa para identificar un archivo abierto. Si obtiene un valor 3, en algún lugar, el sistema operativo está siguiendo la pista que 3 se refiere a , o lo que sea. Es un pequeño valor breve para indicar al sistema operativo qué archivo leer. Cuando llama al open y abre, por ejemplo, foo.txt, el sistema operativo dice, "ok, archivo abierto, llamándolo 3 desde aquí en adelante".

1

Si el programa utiliza fopen() continuación, un paquete de amortiguación utilizará una llamada sistema específico de la implementación para obtener un descriptor de archivo y lo almacenará en una estructura FILE.

La llamada al sistema (al menos en Unix, Linux y Mac) buscará (por lo general) un sistema de archivos basado en disco para encontrar el archivo. Crea estructuras de datos en la memoria del kernel que recopila la información necesaria para leer o escribir el archivo.

También crea una tabla para cada proceso que se vincula con las otras estructuras de datos del kernel necesarias para acceder al archivo. El índice en esta tabla es un número (generalmente) pequeño. Este es el descriptor de archivo que se devuelve desde la llamada al proceso del usuario y luego se almacena en la estructura FILE.

4

Esta pregunta no está completamente relacionada con el lenguaje de programación. Aunque la biblioteca tiene un impacto en lo que sucede al abrir un archivo (usando open o fopen, por ejemplo), el comportamiento principal proviene del sistema operativo.

Linux, y supongo que otros sistemas operativos realizan la lectura en la mayoría de los casos. Esto significa que el archivo se lee realmente desde el almacenamiento físico incluso antes de llamar al read para el archivo. Esto se hace como una optimización, reduciendo el tiempo de lectura cuando el usuario realmente lee el archivo. Este comportamiento puede ser controlado parcialmente por el programador, usando un indicador específico para las funciones abiertas. Por ejemplo, la API de Win32 CreateFile puede especificar FILE_FLAG_RANDOM_ACCESS o FILE_FLAG_SEQUENTIAL_SCAN para especificar el acceso aleatorio (en cuyo caso el archivo no se lee con anticipación) o el acceso secuencial (en cuyo caso el sistema operativo realizará una lectura anticipada bastante agresiva), respectivamente. Otras API de OS pueden dar más o menos control.

Para el básico API ANSI C de open, read, write que utilizan un descriptor de archivo, el descriptor de fichero es un número entero simple que se pasa en el OS y significa el archivo. En el sistema operativo en sí esto se suele traducir a una estructura que contiene toda la información necesaria para el archivo (nombre, ruta, desplazamientos de búsqueda, tamaño, búferes de lectura y escritura, etc.). El SO abrirá el archivo, es decir, encontrará la entrada específica del sistema de archivos (un inode en Linux) que se correlaciona con la ruta que proporcionó en el método open, crea la estructura del archivo y devuelve una ID al usuario: el descriptor del archivo. A partir de ese momento, el SO es libre de leer cualquier dato que le parezca adecuado, incluso si el usuario no lo solicita (leer más de lo solicitado a menudo, al menos trabajar en el tamaño nativo del sistema de archivos).

0

Al abrir el archivo, entonces el puntero del archivo obtiene la dirección base de (dirección de inicio) de ese file.Then utiliza diferentes funciones para trabajar en el archivo. EDIT: Gracias a Chris, aquí es la estructura que lleva el nombre ARCHIVO

typedef struct { 
     int    level;  /* fill/empty level of buffer */ 
     unsigned  flags;  /* File status flags   */ 
     char   fd;   /* File descriptor   */ 
     unsigned char hold;  /* Ungetc char if no buffer */ 
     int    bsize;  /* Buffer size    */ 
     unsigned char *buffer; /* Data transfer buffer  */ 
     unsigned char *curp;  /* Current active pointer  */ 
     unsigned  istemp;  /* Temporary file indicator */ 
     short   token;  /* Used for validity checking */ 
}  FILE; 
+0

No exactamente. El "puntero de archivo" a una secuencia (que puede ser un archivo literal u otra cosa) no es un puntero a los datos del archivo, sino que es un puntero a una estructura que almacena información de acceso que incluye el descriptor de archivo subyacente y la lectura puntero. El puntero de lectura normalmente se inicializaría al principio del archivo. Pero la función fopen() devuelve un puntero a la estructura, no a los datos en el archivo. Para obtener un puntero real sin referencias a los datos del archivo, use open() para obtener un descriptor de archivo (en lugar de fopen()) y luego mmap(). –

+0

Las estructuras de archivos dependen del sistema operativo. Algunas estructuras pueden contener el sector lógico y el número de plato del inicio del archivo. Otros pueden contener permisos y el nombre del archivo. –

Cuestiones relacionadas