manejo lenguaje fputs ejercicios ejemplos binarios archivos c file posix libc

lenguaje - manejo de archivos en c ejemplos



¿Hay alguna razón común para usar open() en lugar de fopen()? (7)

Estoy haciendo un pequeño proyecto en C después de bastante tiempo lejos de eso. Éstos incluyen incluir algún manejo de archivos. Observé en diversos documentos que hay funciones que devuelven identificadores FILE * y otras que devuelven descriptores (entero pequeño). Ambos conjuntos de funciones ofrecen los mismos servicios básicos que necesito, así que realmente no importa que los use.

Pero tengo curiosidad sobre la sabiduría de la colección: ¿es mejor usar fopen() y amigos, o open() y amigos?

Editar Como alguien mencionó los dispositivos de almacenamiento en búfer frente a los nobuferados y los que acceden, debo agregar que una parte de este pequeño proyecto estará escribiendo un controlador de sistema de archivos de espacio de usuario en FUSE. Por lo tanto, el acceso a nivel de archivo podría ser tan fácil en un dispositivo (por ejemplo, un CDROM o una unidad SCSI) como en un "archivo" (es decir, una imagen).


Es mejor usar open () si se apega a los sistemas tipo Unix y es posible que desee:

  • Tenga un control más preciso sobre los bits de permisos de Unix en la creación de archivos.
  • Utilice las funciones de nivel inferior como leer / escribir / mmap en lugar de las funciones de E / S de flujo en búfer C.
  • Usar el descriptor de archivo (fd) basado en la programación de IO (sondeo, selección, etc.) Por supuesto, puede obtener un fd de un ARCHIVO * usando fileno (), pero se debe tener cuidado de no mezclar las funciones de flujo basadas en FILE * con funciones basadas en fd .
  • Abra cualquier dispositivo especial (no un archivo normal)

Es mejor usar fopen / fread / fwrite para una portabilidad máxima, ya que estas son funciones C estándar, las funciones que he mencionado anteriormente no lo son.


Fopen y sus primos están protegidos. abrir, leer y escribir no están almacenados en el búfer. Su aplicación puede o no importarle.

fprintf y scanf tienen una API más rica que le permite leer y escribir archivos de texto formateados. lectura y escritura usan matrices fundamentales de bytes. Las conversiones y el formato deben estar hechos a mano.

La diferencia entre los descriptores de archivos y (ARCHIVO *) es realmente inconsecuente.

Cachondo


La objeción de que "fopen" es portátil y "abierta" no es falsa.

fopen es parte de libc, open es una llamada al sistema POSIX.

Cada uno es tan portátil como el lugar del que provienen.

I / O a archivos fopen''ed es (debe asumir que puede ser, y para fines prácticos, está) almacenado en buffer por libc, los descriptores de archivos abiertos () ''ed no están almacenados en búfer por libc (pueden ser, y por lo general son almacenado en el sistema de archivos, pero no todo lo que abre () es un archivo en un sistema de archivos.

¿Qué sentido tiene fopen''ing, por ejemplo, un nodo de dispositivo como / dev / sg0, por ejemplo, o / dev / tty0 ... ¿Qué vas a hacer? ¿Vas a hacer un ioctl en un ARCHIVO *? Buena suerte con eso.

Tal vez quieras abrir con algunas banderas como O_DIRECT - no tiene sentido con fopen ().


Sí. Cuando necesita un control de bajo nivel.

En los sistemas operativos UNIX, generalmente puede intercambiar manejadores de archivos y conectores.

Además, los controladores de bajo nivel mejoran la compatibilidad ABI con respecto a los indicadores FILE.


fopen funciona en un nivel superior al abierto .... fopen le devuelve un puntero a la secuencia FILE que es similar a la abstracción de la secuencia que lee en C ++

open le devuelve un descriptor de archivo para el archivo abierto ... No le proporciona una abstracción de flujo y usted es responsable de manejar los bits y bytes usted mismo ... Esto está en un nivel inferior en comparación con fopen

Las corrientes Stdio se almacenan en el búfer, mientras que los descriptores de archivos open () no lo son. Depende de lo que necesites. También puedes crear uno a partir del otro:

int fileno (FILE * stream) devuelve el descriptor de archivo para un FILE *, FILE * fdopen (int fildes, const char * mode) crea un FILE * desde un descriptor de archivo.

Tenga cuidado al entremezclar IO con búfer y sin búfer, ya que perderá lo que hay en su búfer cuando no lo vacía con fflush ().


por lo general, debe favorecer el uso de la biblioteca estándar (fopen). Sin embargo, hay ocasiones en las que deberá usar abrir directamente.

Un ejemplo que viene a la mente es solucionar un error en una versión anterior de Solaris que hizo que fopen fallara después de que se abrieron 256 archivos. Esto fue porque utilizaron erronicamente un char sin signo para el campo fd en su implementación struct FILE en lugar de un int. Pero este fue un caso muy específico.


read () y write () usan E / S sin búfer. ( fd : descriptor de archivo entero)

fread () y fwrite () utilizan E / S en búfer. (Puntero de estructura FILE * )

Los datos binarios escritos en una tubería con escritura () pueden no ser capaces de leer datos binarios con fread () , debido a alineaciones de bytes, tamaños variables, etc. Es un disparate.

La mayoría de los códigos de controladores de dispositivos de bajo nivel utilizan llamadas de E / S sin búfer.

La mayoría de las E / S de nivel de aplicación utilizan buffer.

El uso del ARCHIVO * y sus funciones asociadas es correcto, máquina por máquina, pero la portabilidad se pierde en otras arquitecturas en la lectura y escritura de datos binarios. fwrite () es una E / S con búfer y puede generar resultados poco fiables si se escribe para una arquitectura de 64 bits y se ejecuta en un 32 bits; o (Windows / Linux). La mayoría de los sistemas operativos tienen macros de compatibilidad dentro de su propio código para evitar esto.

Para la portabilidad binaria de E / S de bajo nivel, read () y write () garantizan las mismas lecturas y escrituras binarias cuando se compilan en diferentes arquitecturas. Lo básico es escoger de una manera u otra y ser consecuente con eso, en todo el conjunto binario.

<stdio.h> // mostly FILE* some fd input/output parameters for compatibility // gives you a lot of helper functions --> List of Functions Function Description ─────────────────────────────────────────────────────────────────── clearerr check and reset stream status fclose close a stream fdopen stream open functions //( fd argument, returns FILE*) feof check and reset stream status ferror check and reset stream status fflush flush a stream fgetc get next character or word from input stream fgetpos reposition a stream fgets get a line from a stream fileno get file descriptor // (FILE* argument, returns fd) fopen stream open functions fprintf formatted output conversion fpurge flush a stream fputc output a character or word to a stream fputs output a line to a stream fread binary stream input/output freopen stream open functions fscanf input format conversion fseek reposition a stream fsetpos reposition a stream ftell reposition a stream fwrite binary stream input/output getc get next character or word from input stream getchar get next character or word from input stream gets get a line from a stream getw get next character or word from input stream mktemp make temporary filename (unique) perror system error messages printf formatted output conversion putc output a character or word to a stream putchar output a character or word to a stream puts output a line to a stream putw output a character or word to a stream remove remove directory entry rewind reposition a stream scanf input format conversion setbuf stream buffering operations setbuffer stream buffering operations setlinebuf stream buffering operations setvbuf stream buffering operations sprintf formatted output conversion sscanf input format conversion strerror system error messages sys_errlist system error messages sys_nerr system error messages tempnam temporary file routines tmpfile temporary file routines tmpnam temporary file routines ungetc un-get character from input stream vfprintf formatted output conversion vfscanf input format conversion vprintf formatted output conversion vscanf input format conversion vsprintf formatted output conversion vsscanf input format conversion

Entonces, para un uso básico, yo personalmente usaría lo anterior sin mezclar demasiado las expresiones idiomáticas.

Por el contrario,

<unistd.h> write() lseek() close() pipe() <sys/types.h> <sys/stat.h> <fcntl.h> open() creat() fcntl() all use file descriptors.

Estos proporcionan un control detallado sobre la lectura y la escritura de bytes (recomendado para dispositivos especiales y fifos (tuberías)).

Entonces, de nuevo, use lo que necesita, pero mantenga la coherencia en sus expresiones idiomáticas e interfaces. Si la mayoría de su base de código usa un modo, utilícelo también, a menos que haya una razón real para no hacerlo. Ambos conjuntos de funciones de biblioteca de E / S son extremadamente confiables y se usan millones de veces al día.

Nota: Si está interactuando con CI / O con otro idioma, (perl, python, java, c #, lua ...) compruebe lo que recomiendan los desarrolladores de esos idiomas antes de escribir su código C y ahorrarse algunos problemas.