¿Cuál es la diferencia entre un descriptor de archivo y un puntero de archivo?

6 minutos de lectura

avatar de usuario de karthi_ms
karthi_ms

¿Cómo se relacionan los descriptores de archivo y los punteros de archivo? ¿Cuándo es apropiado usar cada uno?

avatar de usuario de unwind
relajarse

Un descriptor de archivo es un “identificador” de enteros de bajo nivel que se utiliza para identificar un archivo abierto (o socket, o lo que sea) a nivel de kernel, en Linux y otros sistemas similares a Unix.

Pasa descriptores de archivo “desnudos” a llamadas Unix reales, como read(), write() y así.

A FILE puntero es una construcción de nivel de biblioteca estándar de C, que se utiliza para representar un archivo. Él FILE envuelve el descriptor de archivo y agrega almacenamiento en búfer y otras funciones para facilitar la E/S.

Pasas FILE punteros a funciones C estándar tales como fread() y fwrite().

  • @nvl: fildes seguramente está disponible para Windows, por ejemplo msdn.microsoft.com/en-us/library/z0kc8e3z%28VS.80%29.aspx

    – kennytm

    11 de marzo de 2010 a las 9:16

  • @unwind ¿Qué quiso decir con descriptores de archivo “desnudos”? La referencia vinculada dice que el fd es el primer argumento para read(). ¿Por qué lo llamas desnudo?

    – Adicto

    27 de julio de 2014 a las 9:37


  • @Geek en comparación con la biblioteca estándar FILE * tipo, el descriptor de archivo entero es “menos envuelto”, es decir, “desnudo”.

    – relajarse

    30 de julio de 2014 a las 16:40

  • Si bien este comentario suena autorizado (y podría muy bien serlo), encontré que los comentarios de Suraj Jain y Vogeesh HT son más informativos y proporcionaron un nivel de detalle necesario que no está disponible en los otros comentarios.

    – Estado Machino

    20 de julio de 2021 a las 3:58

Avatar de usuario de Ben
ben

Uno está protegido (FILE *) y el otro no. En la práctica, desea utilizar FILE * casi siempre cuando está leyendo un archivo ‘real’ (es decir, en el disco), a menos que sepa lo que está haciendo o que su archivo sea realmente un socket o algo así.

Puede obtener el descriptor de archivo de la FILE * usando fileno() y puedes abrir un búfer FILE * de un descriptor de archivo usando fdopen()

  • +1 por señalar fileno(), la organización de las páginas de manual hace que este sea difícil de encontrar. Lo mismo para fdopen().

    – BD en Rivenhill

    30 de abril de 2010 a las 16:29

Avatar de usuario de Martin Wickman
Martín Wickmann

Un descriptor de archivo es solo un número entero que obtiene del POSIX open() llamada. Usando el estándar C fopen() obtienes un FILE volver a estructurar. Él FILE struct contiene este descriptor de archivo, entre otras cosas, como el indicador de fin de archivo y de error, la posición de la transmisión, etc.

entonces usando fopen() le da una cierta cantidad de abstracción en comparación con open(). En general, deberías estar usando fopen() ya que es más portátil y puede usar todas las otras funciones estándar de C que usan el FILE estructura, es decir, fprintf() y familia.

No hay problemas de rendimiento al usar ninguno de los dos.

  • +1 por mencionar la portabilidad. ARCHIVO es parte de la biblioteca C estándar (de vuelta a C89/C90); los descriptores de archivos no lo son.

    – tomlogic

    11 de marzo de 2010 a las 17:42

Descriptor de archivo frente a puntero de archivo

Descriptor de archivo:

File Descriptor es un valor entero devuelto por open() llamada del sistema.

int fd = open (filePath, mode);

  1. Manejador de nivel bajo/Kernel.
  2. pase a read() y write() de UNIX System Calls.
  3. No incluye almacenamiento en búfer y características similares.
  4. Menos portátil y carece de eficiencia.

Puntero de archivo:

File Pointer es un puntero a una estructura C devuelta por fopen() función de biblioteca, que se utiliza para identificar un archivo, envolver el descriptor de archivo, funcionalidad de almacenamiento en búfer y todas las demás funciones necesarias para la operación de E/S.El puntero del archivo es de tipo EXPEDIENTEcuya definición se encuentra en “/usr/incluir/stdio.h”. Esta definición puede variar de un compilador a otro.

FILE *fp = fopen (filePath, mode);

// A FILE Structure returned by fopen 
    typedef struct 
    {
        unsigned char   *_ptr;
        int     _cnt;
        unsigned char   *_base;
        unsigned char   *_bufendp;
        short   _flag;
        short   _file;
        int     __stdioid;
        char    *__newbase;
#ifdef _THREAD_SAFE
        void *_lock;
#else
        long    _unused[1];
#endif
#ifdef __64BIT__
        long    _unused1[4];
#endif /* __64BIT__ */
    } FILE;
  1. Es una interfaz de alto nivel.
  2. Pasado a las funciones fread() y fwrite().
  3. Incluye almacenamiento en búfer, indicación de error y detección EOF, etc.
  4. Proporciona mayor portabilidad y eficiencia.

Quiere agregar puntos que podrían ser útiles.

ACERCA DE FILE *

  1. no se puede utilizar para la comunicación entre procesos (IPC).
  2. Úselo cuando necesite E/S almacenada en búfer de propósito general. (printf, frpintf, snprintf, scanf)
  3. Lo uso muchas veces para los registros de depuración. ejemplo,

                 FILE *fp;
                 fp = fopen("debug.txt","a");
                 fprintf(fp,"I have reached till this point");
                 fclose(fp);
    

ACERCA DE FILE DESCRIPTOR

  1. Generalmente se utiliza para IPC.

  2. Brinda control de bajo nivel a los archivos en sistemas * nix (dispositivos, archivos, sockets, etc.), por lo tanto, es más poderoso que el FILE *.

  • no puedes usar fdopen() para hacer cosas como IPC y dispositivos con FILE*?

    – osvein

    21 de marzo de 2017 a las 13:47


  • En realidad, tanto sí como no. No puede configurar e inicializar IPC con FILE*pero puedes crear un FILE* de un descriptor de archivo (fdopen()) y luego cerrando el FILE también cerrará el descriptor. Por lo tanto, puedes hacer IPC, pero tiene que lidiar un poco con los descriptores de archivos para facilitar cualquier IPC directo.

    – Miqueas W.

    10 de enero de 2018 a las 22:55

FILE * es más útil cuando trabaja con archivos de texto y entrada/salida del usuario, porque le permite usar funciones API como sprintf(), sscanf(), fgets(), feof() etc.

La API del descriptor de archivos es de bajo nivel, por lo que permite trabajar con sockets, conductos, archivos mapeados en memoria (y archivos normales, por supuesto).

  • no puedes usar fdopen() para hacer cosas como IPC y dispositivos con FILE*?

    – osvein

    21 de marzo de 2017 a las 13:47


  • En realidad, tanto sí como no. No puede configurar e inicializar IPC con FILE*pero puedes crear un FILE* de un descriptor de archivo (fdopen()) y luego cerrando el FILE también cerrará el descriptor. Por lo tanto, puedes hacer IPC, pero tiene que lidiar un poco con los descriptores de archivos para facilitar cualquier IPC directo.

    – Miqueas W.

    10 de enero de 2018 a las 22:55

Solo una nota para terminar la discusión (si está interesado)….

fopen puede ser inseguro, y probablemente deberías usar fopen_s o open con juego de bits exclusivo. C1X está ofreciendo x modos, para que pueda fopen con modos "rx", "wx"etc.

Si utiliza openusted podría considerar open(..., O_EXCL | O_RDONLY,... ) o open(..., O_CREAT | O_EXCL | O_WRONLY,... ).

Véase, por ejemplo, No haga suposiciones sobre fopen() y la creación de archivos.

  • Como fopen_s no parece estar disponible con POSIXsupongo que la solución más portátil sería open(2) y entonces fdopen(2). (dejando las ventanas a un lado). Además, ¿qué sería más rápido? fopen_s() o open(2) seguido por fdopen(2)?

    – Mihir Lutra

    10 de agosto de 2019 a las 18:08

¿Ha sido útil esta solución?