2009-11-01 19 views
161

¿Hay alguna razón (aparte de los sintácticos) que te gustaría utilizarC fopen vs abierta

FILE *fdopen(int fd, const char *mode); 

o

FILE *fopen(const char *path, const char *mode); 

en lugar de

int open(const char *pathname, int flags, mode_t mode); 

al utilizar C en un entorno Linux?

+0

¿Quisces decir 'fdopen' y' open' o 'fopen' y' open'? – user7116

+0

¿No quieres decir fopen, not fdopen? – Omnifarious

+6

'fopen' es parte de la biblioteca estándar de C,' open' no lo es. Use 'fopen' cuando escriba código portátil. – Aziz

Respuesta

183

Existen cuatro razones principales para usar fopen en lugar de abrir.

  1. fopen te ofrece la buffering IO que pueden llegar a ser mucho más rápido que lo que está haciendo con open.
  2. fopen hace que la línea termine la traducción si el archivo no se abre en modo binario, lo que puede ser muy útil si su programa alguna vez se transfiere a un entorno que no sea de Unix.
  3. A FILE * le da la posibilidad de usar fscanf y otras funciones stdio.
  4. Su código puede algún día tener que ser portado a alguna otra plataforma que solo admita ANSI C y no admita la función open.

En mi opinión, la terminación de línea de traducción más a menudo se interpone en su camino que ayuda, y el análisis de fscanf es tan débil que inevitablemente termina lanzándolo a favor de algo más útil.

Y la mayoría de las plataformas que admiten C tienen una función open.

Eso deja la pregunta de almacenamiento en búfer.En los lugares en los que principalmente lee o escribe un archivo secuencialmente, la compatibilidad con el almacenamiento en búfer es realmente útil y mejora la velocidad. Pero puede llevar a algunos problemas interesantes en los que los datos no terminan en el archivo cuando espera que estén allí. Debe recordar fclose o fflush en los momentos apropiados.

Si está haciendo búsquedas, la utilidad del almacenamiento en memoria intermedia disminuye rápidamente.

Por supuesto, mi tendencia es que tiendo a trabajar con sockets mucho, y ahí el hecho de que realmente quieres estar haciendo IO sin bloqueo (que FILE * no admite totalmente de manera razonable) sin el almacenamiento en búfer y, a menudo tienen requisitos de análisis complejos realmente colorean mis percepciones.

+3

No voy a cuestionar tus experiencias, pero me encantaría oírte elaborar un poco sobre esto. ¿Para qué tipo de aplicaciones cree que el almacenamiento en búfer incorporado se interpone en el camino? ¿Cuál es el problema exactamente? –

+0

No vi el último párrafo. Punto válido, en mi humilde opinión. Por lo que puedo decir, la pregunta era sobre el archivo IO. –

+0

Casi cualquier programa que no transmita IO, donde termina haciendo busca en el medio del archivo. Debería actualizar mi respuesta para aclarar. – Omnifarious

11

Si usted tiene un FILE *, puede utilizar funciones como fscanf, fprintf y fgets etc Si usted tiene sólo el descriptor de archivo, usted ha limitado (pero probablemente más rápido) de entrada y salida rutinas read, etc. write

40

open() es una llamada de sistema operativo de bajo nivel. fdopen() convierte un descriptor de archivo de nivel de os a la abstracción de ARCHIVO de nivel superior del lenguaje C. fopen() llama al open() en segundo plano y le proporciona un puntero ARCHIVO directamente.

El uso de descriptores de archivos bastante crudos tiene varias ventajas, que incluyen una mayor facilidad de uso pero también otras ventajas técnicas como el almacenamiento en búfer integrado. Especialmente el almacenamiento en búfer generalmente resulta en una ventaja de rendimiento considerable.

+2

¿Hay alguna desventaja al usar las versiones 'f ...' en búfer de open? – LJM

+3

@L. Moser, sí, cuando ya está almacenando en búfer los datos y, por lo tanto, el búfer adicional agrega copias innecesarias y gastos generales de memoria. –

+5

en realidad hay otras desventajas. 'fopen()' no proporciona el mismo nivel de control al abrir archivos, por ejemplo, crea permisos, comparte modos y más.típicamente 'open()' y variantes proporcionan mucho más control, cerca de lo que el sistema operativo realmente proporciona –

10

A menos que sea parte del 0.1% de las aplicaciones donde usar open es un beneficio de rendimiento real, realmente no hay una buena razón para no usar fopen. En lo que respecta al fdopen, si no está jugando con los descriptores de archivos, no necesita esa llamada.

del palillo con el fopen y su familia de métodos (fwrite, fread, fprintf, et al) y usted será muy satisfechos. Igualmente importante, otros programadores estarán satisfechos con su código.

6

Usar abrir, leer, escribir significa que debe preocuparse por las interacciones de señal.

Si la llamada fue interrumpida por un manejador de señal, las funciones devolverán -1 y establecerán errno en EINTR.

Así que la forma correcta de cerrar un archivo sería

while (retval = close(fd), retval == -1 && ernno == EINTR) ; 
+4

Para 'cerrar', esto depende del sistema operativo. Es incorrecto hacer el ciclo en Linux, AIX y algunos otros sistemas operativos. – strcat

1

he cambiado a abrir() desde fopen() para mi aplicación, ya que estaba causando fopen doble lee cada vez que me encontré fgetc fopen. Las lecturas dobles fueron perjudiciales para lo que estaba tratando de lograr. open() parece hacer lo que le pides.

-1

abrir un archivo mediante fopen
antes de que podamos leer (o escribir) información de (a) un archivo en un disco hay que abrir el archivo. para abrir el archivo que hemos llamado la función fopen.

1.firstly it searches on the disk the file to be opened. 
2.then it loads the file from the disk into a place in memory called buffer. 
3.it sets up a character pointer that points to the first character of the buffer. 

éste el camino del comportamiento de fopen función
hay algunas causas mientras que el proceso de amortiguación, puede timedout. entonces al comparar fopen (alto nivel de E/S) a abrir (bajo nivel de I/O) llamada al sistema, y ​​es un más rápido más apropiado que fopen.

+0

está abierto más rápido que fopen? – obayhan

+0

sí, ** abrir ** es la llamada al sistema, que es más rápido que fopen - comparitively @obayhan – prashad

4

open() es una llamada al sistema y específica para el sistema basado en Unix y devuelve un descriptor de archivo. Puede escribir en un descriptor de archivo utilizando el write() que es otra llamada al sistema.
fopen() es una llamada de función ANSI C que devuelve un puntero de archivo y es portátil para otros sistemas operativos. Podemos escribir en el puntero de archivo usando fprintf.

En Unix:
Usted puede obtener un puntero de archivo del descriptor de fichero usando:
fP = fdopen(fD, "a");
Usted puede obtener un descriptor de archivo del puntero del archivo utilizando:
fD = fileno (fP);

4

abierta() se llamará al final de cada una de las funciones de la familia fopen().open() es una llamada de sistema y fopen() las proporcionan las bibliotecas como funciones de contenedor para el usuario fácil de uso

20

fopen vs abierta en C

1) fopen es una biblioteca función mientras que open es una llamada al sistema .

2) fopen proporciona tamponada IO que es más rápido en comparación con el que es opensin buffer.

3) fopen es portátil mientras open no portátil (abierto es entorno específico).

4) fopen devuelve un puntero a una estructura de archivo (ARCHIVO *); open devuelve un número entero que identifica el archivo.

5) A FILE * le da la posibilidad de usar fscanf y otras funciones stdio.

+1

'open' es un estándar POSIX, por lo que es bastante portátil – Spookbuster

1

Depende también de qué indicadores se requieren para abrir. Con respecto al uso de escritura y lectura (y portabilidad) se debe usar f *, como se argumentó anteriormente.

Pero si básicamente quieres especificar más que los indicadores estándar (como rw y anexar indicadores), tendrás que usar una API específica de la plataforma (como POSIX open) o una biblioteca que abstraiga estos detalles. El C-estándar no tiene tales banderas.

Por ejemplo, es posible que desee abrir un archivo, solo si se cierra. Si no especifica la marca de creación, el archivo debe existir. Si agrega exclusivo para crear, solo creará el archivo si no existe. Hay muchos más.

Por ejemplo, en los sistemas Linux, hay una interfaz de LED expuesta a través de sysfs. Expone el brillo del led a través de un archivo. Escribir o leer un número como una cadena de 0-255. Por supuesto, no desea crear ese archivo y solo escribirlo, si existe. Lo bueno de ahora es: use fdopen para leer/escribir este archivo usando las llamadas estándar.