ARCHIVOS

FUJOS Y ARCHIVOS (FILES)

El sistema de I/O (Input/Output) del C ofrece al programador en C un consistente interfaz independiente de la hardware. En otras palabras, el sistema de I/O ofrece un cierto nivel de abstracción entre el programa y el dispositivo en uso.
Esta abstracción se llama flujo, y el dispositivo donde se fijan los datos archivo (en inglés file.
El sistema ANSI del C es estudiado para ser utilizado con una amplia gama de dispositivos entre los que se encuentran los terminales, unidades de disco e lectores de cintas. Aunque los dispositivos sean diferentes entre sí, el sistema ANSI del C los transforma en unidades lógicas con un dispositivo único llamado flujo. Todos los flujos se comportan de modo análogo y son independientes de la hardware. Las funciones empleadas para escribir en el disco pueden ser utilizadas para escribir en la pantalla o en la impresora.
En este sentido se distinguen dos tipos de flujo: de texto y binario.

Flujo de Texto

Un flujo de texto es un secuencia de caracteres. En el interior de un flujo de texto se pueden efectuar conversiones de caracteres según la necesidad. Por ejemplo, un carácter de línea nueva se puede convertir en un carácter de retorno del carro mas un carácter de salto de línea.

Flujo binario

Se entiende por flujo binario a una secuencia de bytes que tienen una relación de uno a uno con la secuencia del dispositivo externo. En este tipo de flujos no tiene lugar ninguna conversión como en el caso anterior.

ARCHIVO (FILE)

Un archivo (file) es un concepto lógico que puede ser aplicado a cualquier cosa, desde datos del disco hasta terminales. Mediante la apertura de un archivo se asocia un flujo de datos entre este y el computador a través del programa correspondiente.

EL SISTEMA ANSI DE ENTRADA Y SALIDA (INPUT/OUTPUT)

Este sistema comprende numerosas funciones unidas entre ellas. Para poder utilizarlas es indispensable incluir el archivo stdio.h (standard input/ouput).

Punteros de archivo

El interfaz que une el sistema ANSI de I/O del C es el puntero de archivo definido con el tipo FILE el cual representa una estructura (más adelante se verá el concepto structur que contiene información del archivo como el nombre del mismo, el status, la posición del la ventana de lectura etc. El tipo FILE utilizado para la declaración de un putero de archivo se encuentra definido en stdio.h.
La creación de una variable puntero de archivo sería:

  • FILE *fp;

donde fp representaría la variable identificadora del flujo.

Apertura de archivo: fopen()

La función fopen() tiene dos objetivos: primero abrir el flujo y asociarlo al archivo correspondiente y segundo pasar a la variable puntero la dirección de la estructura que contiene los datos correspondientes a dicho archivo.

  • #include <stdio.h>
    FILE *fopen(char *name, char *mode);

donde name es el nombre del archivo y mode es el modo con el que se tiene acceso a los datos de dicho archivo. El nombre de un archivo tiene que ser conforme con la sintaxis del sistema operativo correspondiente. En el DOS puede requerir la ruta del archivo (path).

En caso de faltar la especificación b o t que indica el modo binario o el modo de texto el modo lo marca la variable _fmode cuyo valor es uno de los dos definidos en el archivo fcntl.h O_TEXT o O_BINARY.
En el caso de "w+" si el archivo existe se sobrescribe sobre él.

 

Mode

Significado

"r"

Apertura un archivo para la lectura

"w"

Creación de un archivo para la escritura

"a"

Añadir al final del archivo

"rb"

Apertura de un archivo binario

"wb"

Creación de un archivo binario en escritura

"ab"

Añadir a un archivo binario

"r+"

Apertura de un archivo para la lectura y la escritura

"w+"

Creación de un archivo para lectura y escritura

"a+"

Añadir al final o creación de un archivo para lectura y escritura

"r+b"

Apertura de un archivo binario para la lectura y para la escritura

"w+b"

Creación de un archivo binario para la lectura y para la escritura

"a+b"

Añadir al final o creación de un archivo binario en lectura/escrit.

"rt"

Apertura de un archivo de texto en para la lectura

"wt"

Creación de un archivo de texto para la escritura

"at"

Añadir al final de un archivo de texto.

"r+t"

Apertura de un archivo de texto en lectura y escritura

"w+t"

Creación de un archivo de texto en lectura y escritura

"a+t"

Añadir al final o creación de un archivo de texto lectura/escritura

 
  • #include <stdio.h>
    main()
  • {

  • FILE *fp;
    fp=fopen("info.txt","r");/* Apertura per la lettura */
    if(fp==NULL) /* NULL è definita in stdio.h */

  • puts("\n impossibilità di aprire il file ");
    return 1;

  • return 0;
  • }
 

Funciones para el acceso a archivos de tipo texto (ASCII).

Las funciones que siguen leen o escriben datos en archivos cuyos datos son de tipo ASCII.

Lectura de caracteres: getc()

Las funciones getc() permite leer caracteres en un flujo abierto en modo de lectura ("r")

  • #include <stdio.h>
    int getc(FILE *fp);

donde pf es un puntero de archivo de tipo FILE que es obtenido por medio de la función fopen(). Por razones históricas getch() retorna un valor de tipo entero (int) en el cual el byte superior es cero.
getch() retorna EOF (Ende Of File o final de archivo) cuando llega al final del archivo o cuando se verifica un error

Escritura de caracteres: putc()

La función putc() permite escribir caracteres en un flujo abierto precedentemente con la función fopen() para la escritura ("w").

  • #include <stdio.h>
    int putc(int car, FILE *fp);

donde fp es un puntero de file y car el carácter que se desea escribir en el archivo. Por razones históricas car es de tipo entero (int) en el cual el byte superior es cero.
Si la escritura se realiza con éxito la función retorna el carácter escrito. Si no retorna EOF (Ende Of File o final de archivo)

 
  • #include <stdio.h>
    main()
  • {

  • FILE *fp;
    fp=fopen("info.txt","r");/* Apertura para la lectura */
    if(fp==NULL) /* NULL esta definida en stdio.h */

  • puts("\n inposibilidad de abrir el archivo");
    return 1;

  • do ch=getc(fp); while(ch!=EOF);
    return 0;
  • }
 

Lectura de una cadena de caracteres (strings): fgets()

La función fgets() lee caracteres provenientes de un flujo hasta encontrar un carácter de nueva línea y hasta un máximo de caracteres especificado por el parámetro n.

  • #include <stdio.h>
    char *fgets(char*str,int n,FILE *fp);

El número máxima de caracteres leídos es n-1 incluido el carácter nueva línea `\n'. El string resultante termina con `\0'.

Escritura de una cadena de caracteres (strings): fputs()

La función fputs() escribe un string en flujo

  • #include <stdio.h>
    int fputs(char *str,FILE *fp);

fputs() retorna el último carácter escrito. En caso de error retorna EOF

Acceso a archivos de tipo binario.

Las funciones que siguen leen datos aunque no sean de tipo ASCII.

Lectura de archivo: fread()

La función fread() permite leer datos de cualquier tipo.

  • #include <stdio.h>
    unsigned fread(void *buffer,size_t lenb,size_t n,
    FILE *fp);

Donde buffer es un puntero al área de memoria que recibe los datos leídos del archivo, lenb. es el tamaño en bytes de un bloque y n el número de bloques que se desean leer. fp es un puntero de file a un flujo abierto precedentemente.
La función fread() retorna el número de bloques leídos que deberá ser n. En caso de error o de alcanzar el final del archivo retorna un número diferente a n (posiblemente 0).

Escritura en un archivo: fwrite()

La función fwrite() permite escribir datos de cualquier tipo.

  • #include <stdio.h>
    unsigned fwrite(void *buffer,size_t lb,size_t n, FILE *fp);

Donde buffer es un puntero al área de memoria que contiene los datos para escribir en el archivo, lenb. es el tamaño en bytes de un bloque y n el número de bloques que se desean escribir. fp es un puntero de file a un flujo abierto precedentemente.
La función fwrite() retorna el números de bloques escritos que deberá ser n. En caso de error o de alcanzar el final del archivo retorna un número diferente a n (posiblemente 0).

Funciones para el control de archivos

Las funciones que siguen permiten controlar la posición de los datos.

Control del final del archivo: feof()

La función feof() detecta la marca de final de archivo que se haya podido alcanzar durante la lectura de datos.

  • #include <stdio.h>
    int feof(FILE *fp);

Si se ha llegado al final del archivo la función retorna un valor diferente de cero (TRUE). en caso contrario retorna cero (FALSE)

En el ejemplo anterior se podría haber sustituido el ciclo do.. while por

  • while(!feof(fp)) ch=getc(fp);

Posición al inicio de un archivo: rewind()

La funciòn rewind() posiciona la ventana de acceso al archivo al principio del mismo

  • #include <stdio.h>
    void rewind(FILE *fp);

Posicionamiento aleatorio de acceso a un archivo: fseek()

La función fseek() posiciona la ventana de acceso al archivo en cualquier posición deseada.

  • #include <stdio.h>
    int fseek(FILE *fp,long numbyte,int origine);

En este caso fp es un puntero a un archivo obtenido con la llamada de fopen(); num byte es un entero largo que representa el número de bytes a contar desde el origen dado en origine para llegar a la posición final.
En la tabla que sigue se expresan los valores que puede tomar origine junto con los macros definidos en stdio.h que expresan dichos valores.

Si origine es igual a SEEK_SET numbyte expresa el numero de bytes a contar desde la posición inicial hacia adelante.
Si origine es igual a SEEK_CUR numbyte expresa el numero de bytes a contar desde la posición actual hacia adelante.
Si origine es igual a SEEK_END numbyte expresa el numero de bytes a contar desde la posición final hacia atrás.

 

Origine

Nombre del macro

valor

Inicio del file

SEEK_SET

0

Posición corriente

SEEK_CUR

1

Fin del file

SEEK_END

2

Control de errores: ferror()

La función ferror() permite determinar si se ha cometido un error durante la última operación de acceso al archivo.

  • #include <stdio.h>
    int ferror(FILE *fp);

Si ha tenido lugar un error durante la última operación de acceso al archivo la función retorna un valor diferente a cero (TRUE) en caso contrario retorna cero (FALSE).

Control de posición ftell()

Retorna la posicion actual en bytes de puntero de lectura del archivo

  • #include <stdio.h>
    long int ftell(FILE *fp);
 
  •  
  • #include <stdio.h>
    main()
  • {

  • FILE *fp;
    long int pos;
    char s[80];
    fp = fopen( "MyFile", "w+" );
    pos = ftell( fp );
    fputs( "Hello world.", fp );
    fseek( fp, pos, SEEK_SET );
    fgets( s, 80, fp );
    printf( "You read: %s\n", s );
    fclose( fp );
  • }
 

Clausura de un Archivo fclose()

La función fclose() cierra un flujo abierto con una llamada a fopen() despues de haber almacenado los datos en el archivo correspondiente a dicha llamada. La omisión de esta función puede causar varios problemas como pérdida datos, destrucción del archivo o posibles errore en el programa. Por otra parte la función fclose(), libera el bloque de control del archivo asociado al flujo dejándolo nuevamente disponible.

  • #include <stdio.h>
    int fclose(fp);

donde fp es el pntero de archivo retornado por la función fopen(). Si el valor de la restitución es cero significa que la operacion ha sido realizada con éxito. Qualquier otro valor señala un error.

 
  • /* En este ejemplo se visualiza un archivo en modo de texto o en modo binario.*/

    #include <conio.h>
    #include <stdio.h>
  • #include <ctype.h>
    #include <stdlib.h>
  • #define B_LEN 1024
    #define TST_LEN 40
    #define MAX_LIN 18
  • char *err_msg[]=

  • "OK",
    "\nERROR1: TIENES QUE DECIRME QUE ARCHIVO QUIERES\n",
    "\nERROR2: NO HE PODIDO ABRIR EL ARCHIVO\n",
    "\nERROR3: TENGO DIFICULTADES EN LEER EL ARCHIVO\n",
    "\nERROR4: NO PUEDEO REBOBINAR EL ARCHIVO\n";
 
  • void err_exit(int err)
  • {

  • printf("%s",err_msg[err]);
    getch();
    exit(err);
  • }
 
  • void tecla(void)
  • {

  • puts("\n******* APRIETA UNA TECLA ********************* ");
  • }
 
  • int main(int argc,char *argv[])
  • {

  • FILE *fp;
    int bin=0,l_cnt=0;
    unsigned char buff[B_LEN];
    size_t len=TST_LEN,n,i;
    if (argc<2) err_exit(1);
    fp=fopen(argv[1],"r");
    if(fp==NULL)err_exit(2);
    n=fread(buff,1,len,fp);
    if(n==-1)err_exit(3);
    for(i=0;i<n;i++)if(!isascii(buff[i]))
    {

  • bin=1; /* binaer fail */
    break;
    }

  • if(fseek(fp,0,SEEK_SET)!=0)err_exit(4); /* rewind */ len=B_LEN;
    while((n=fread(buff,1,len,fp))!=0)
    {

  • for(i=0;i<n;i++)
    {

  • if(bin)
    {

  • if((++l_cnt)==20)
    {

  • printf("\n");
    l_cnt=0;
    }

  • printf("%03o",buff[i]);
    }

else
{

  • if(buff[i]=='\n')
    }

  • l_cnt++;
    puts("");
    }

  • else putch(buff[i]);
    if(l_cnt==MAX_LIN)
    {

  • l_cnt=0
    tecla();
    if(getch()==3)return 0;
    }
  •  
 

if(bin)
  • {
    tecla();
    getch();
    }
 

  • return 0;
    }
    }/*while*/
 
  •  
  • }