Introduccin
Una computadora puede almacenar grandes cantidades de informacin. Puede acceder a ella de manera muy rpida. Para hacer cualquier cosa es necesario tener MEMORIA disponible, para almacenar variables, recordar valores, etc.
Introduccin
B
C
Datos.txt
Memoria RAM
RAM: Random Access Memory. Acceso aleatorio. Voltil, por tanto insegura. Capacidades de cientos de MB. Velocidad de acceso:
133 MHz 8 ns
Memoria RAM
Es necesario
Evitar la volatilidad de la memoria RAM. Aumentar su capacidad a costos razonables. Realizar respaldos de informacin.
HDD
HDD: Hard Drive Disk Acceso aleatorio. Persistente y confiable. Capacidades de decenas de GB. Velocidad de acceso
5 10 ms
Archivos
Los archivos son entidades que define el sistema operativo para identificar un conjunto de datos Un archivo tiene un conjunto de atributos
Nombre y extensin. Ubicacin (muchas veces es solo parte del nombre). Tamao. Tipo. Permisos: Lectura , escritura y ejecucin (puede estar especificado por usuarios y grupos) Fecha de creacin y modificacin.
Archivos
Debido a su facilidad de uso y compresin, muchos sistemas utilizan archivos especiales para manejar dispositivos
Teclado Entrada secuencial Pantalla Salida secuencial Impresora Salida secuencial Red, Serial, paralela E/S secuencial Etc...
Archivos
Se pueden realizar un conjunto de operaciones a travs del sistema operativo con los archivos:
Abrir Cerrar Leer Escribir Mover a una posicin (solo acceso aleatorio)
Archivos
Para abstraer la interaccin entre los archivos y los programas que realicen operaciones sobre ellos, se define el concepto de flujo. Un flujo es como una manguera por donde fluyen datos en uno o ambos sentidos.
Flujos
chao hola
chao
hola
Flujos
VAR
Abrir
Leer Escribir Cerrar hola
Abrir un flujo
Antes de poder utilizar un flujo, debemos abrirlo. Al momento de abrirlo se especifica el modo
Solo lectura (r) Solo escritura (w) Lectura/escritura (rw) Se asigna un descriptor del archivo a nuestro programa Se modifica el estado del archivo
Al abrir:
Abrir un flujo
Estado de un archivo
Si esta abierto para lectura, otros programas pueden tambin abrirlo para lectura, pero no para escritura. Si est abierto para escritura, nadie ms puede abrirlo.
Cerrar un flujo
Al terminar de usarlos, los flujos deben ser cerrados. Al cerrar los flujos, nuevamente se modifica el estado del archivo (para que otros puedan abrirlo). Al salir del programa de manera normal, los flujos se cierran en forma automtica. Si el programa termina de manera anormal, los flujos pueden quedar abiertos.
Los archivos contienen informacin binaria. Esta informacin puede representar cualquier cosa. Los archivos se separan en dos grandes grupos
Al momento de leer, hay que tener claro el tipo de archivo desde el cual se desea leer informacin.
Se pueden leer letras, palabras o frases completas. Por lo general se leen de manera secuencial, desde la primera letra hasta el fin de archivo.
Pueden contener cualquier cosa. Por lo general se leen de manera aleatoria. Pueden contener estructuras de datos.
Escribir en un flujo
Por lo general, el escribir en un flujo no significa que la informacin se guarde de manera inmediata en el archivo.
La operacin de escritura secundaria es muy costosa. en memoria
Escribir en un flujo
2 datos [Llenando buffer]
5 datos
[Llenando buffer]
[Vaciando buffer]
Accin permitida solo para archivos de acceso directo. Al abrir un archivo, se define una posicin al comienzo de este.
Al leer o escribir de manera secuencial, esta posicin se actualiza automticamente a la posicin siguiente.
Se puede modificar de manera manual esta posicin para leer o modificar un datos especifico o en un orden distinto al secuencial.
FILE
EOF
Apertura de flujos
fopen
Devuelve el descriptor del archivo para su uso posterior. NULL en caso de error Nombre del archivo a abrir
Apertura de flujos
r
w a rb
wb
ab r+ w+
a+
r+b w+b a+b
Cierre de flujos
fclose
Cierra un archivo previamente abierto, liberando los recursos asociados al programa. int fclose(FILE* f);
Flujo a cerrar
Apertura y cierre
#include <stdio.h> int main(){ FILE* archivo; archivo = fopen("testt.txt","r"); if(archivo!=NULL){ if(fclose(archivo)!=EOF) printf("Ok!\n"); else printf("Error al cerrar!\n"); }else printf("Error al abrir!\n");
Manejo de errores
En C, muchas funciones modifican una variable global cuando ocurre un error. Esta variable puede ser consultada para saber ms acerca del error. La variable global se llama errno.
Se define en <errno.h>
Se define en <string.h>
Manejo de errores
#include <stdio.h> int main(){ FILE* archivo; archivo = fopen("testt.txt","r"); if(archivo!=NULL){ if(fclose(archivo)!=EOF) printf("Ok!\n"); else printf("Error al cerrar!\n"); }else printf("Error al abrir: %s\n",strerror(errno));
Lectura de carcteres
fgetc
Lee un carcter desde un archivo abierto para lectura. int fgetc(FILE* f);
Descriptor de archivo
Lectura de carcteres
fgets
Lee desde un archivo abierto para lectura hasta un largo fijo o el fin de lnea.
fgets(char* cadena, int longitud, FILE* f);
Descriptor de archivo
Lectura de carcteres
int main(){ FILE* archivo; archivo = fopen("test.txt","r"); if(archivo!=NULL){ char c; do{ c = fgetc(archivo); printf("%c",c); }while(c!=EOF); fclose(archivo); } }
Lectura de carcteres
int main(){ FILE* archivo; archivo = fopen("test.txt","r"); if(archivo!=NULL){ char* res; char cadena[128]; do{ res=fgets(cadena,128,archivo); if(res!=NULL) printf("%s",cadena); }while(res!=NULL); fclose(archivo);
} }
Lectura de carcteres
Una funcin muy til es feof, quien detecta si se ha alcanzado o no el fin de archivo. feof
Descriptor de archivo
Lectura de carcteres
int main(){ FILE* archivo; archivo = fopen("test.txt","r"); if(archivo!=NULL){ char cadena[128]; while(!feof(archivo)){ fgets(cadena,128,archivo); printf("%s",cadena); } fclose(archivo); } }
Lectura de carcteres
Descriptor de archivo
Lectura de carcteres
int main(){ FILE* archivo; archivo = fopen("test.txt","r"); if(archivo!=NULL){ char c; while( fscanf(archivo,"%c",&c)==1 ) printf("%c",c); fclose(archivo); } }
Escritura de carcteres
EOF en caso de error EOF en caso de error Devuelve el numero de transformaciones realizadas con xito.
Escritura de carcteres
archivo2 = fopen("test2.txt","w+"); ... do{ c = fgetc(archivo); if(c!=EOF){ fputc(c,archivo2); printf("%c",c); } }while(c!=EOF);
Escritura de carcteres
do{ res=fgets(cadena,128,archivo); if(res!=NULL){ printf("%s",cadena); fputs(cadena,archivo2);} }while(res!=NULL);
Escritura de carcteres
while( fscanf(archivo,"%c",&c)==1 ){ printf("%c",c); fprintf(archivo2,"%c",c); }
Escritura de carcteres
fflush
Descriptor de archivo
Otros archivos
Archivos de nmeros
Para leer datos desde un archivo de texto como enteros (o nmeros en general) se puede utilizar fscanf. Para escribir datos numricos en archivos de texto se puede utilizar fprintf. Los archivos deben ser abiertos en modo texto. Se utilizan las conversiones %d y %f ya vistas.
Archivos de nmeros
Archivos de nmeros
#include <stdio.h> int main(){ FILE* archivo; archivo = fopen("test3.txt","r"); if(archivo!=NULL){ int ds[4],i; double fs[4]; fscanf(archivo,"%d %d %d %d\n", &ds[0],&ds[1],&ds[2],&ds[3]); fscanf(archivo,"%d, %d, %d, %d\n", &ds[0],&ds[1],&ds[2],&ds[3]); fscanf(archivo,"%lf ; %lf ; %lf ; %lf\n" &fs[0],&fs[1],&fs[2],&fs[3]); fclose(archivo); } }
Archivos mixtos
Archivos de texto con datos alfanumricos Basta con especificar el tipo de conversin deseada para cada tipo de dato.
Archivos mixtos
#include <stdio.h> int main(){ FILE* archivo; archivo = fopen("test4.txt","r"); if(archivo!=NULL){ char visita[32], local[32]; int gvisita, glocal; int r=4; while(1){ r=fscanf(archivo,"%s %d %s %d\n", local,&glocal,visita,&gvisita); if(r!=4) break; if(glocal>gvisita) printf("Gana local (%s)\n",local); else if(glocal<gvisita) printf("Gana visita (%s)\n",visita); else printf("Empate\n"); } fclose(archivo); } return 1; }
Archivos binarios
Deben ser abiertos en modo binario. La informacin se guarda en formato binario. Si se abre el archivo con un editor de texto, aparece basura. Se pueden intercalar distintos tipos de datos
Archivos binarios
fread
void* buffer, size_t num_bytes, unsigned int, size_t cuenta, Nmero de bytes ledos FILE* fp);
Flujo desde donde leer
Archivos binarios
fwrite
size_t fwrite(
void* buffer, size_t num_bytes, size_t cuenta, FILE* fp);
Archivos binarios
sizeof
Entrega el numero de bytes que ocupa un tipo de dato Es un operador calculado en tiempo de compilacin. sizeof(int) 4 int i; sizeof(i) 4
Archivos binarios
void escribir(FILE* archivo){ archivo = fopen("test5.dat","w+b"); if(archivo!=NULL){ int i,k; k=1; for(i=0;i<10;i++){ size_t ws; ws = fwrite(&k,sizeof(k),1,archivo); k=k*2; printf("%d enteros escritos en %d bytes\n",ws, ws*sizeof(int)); } fclose(archivo); } }
Archivos binarios
void leer(FILE* archivo){ archivo = fopen("test5.dat","r+b"); if(archivo!=NULL){ int i,k; while(fread(&k,sizeof(int),1,archivo)==1){ printf("%d\n",k); } fclose(archivo); } }
Archivos binarios
int main(int argc, char* argv[]){ FILE* archivo; printf("%s",argv[1]); if(argc>1 && strcmp(argv[1],"w")==0) escribir(archivo); else leer(archivo); return 1;
Archivos binarios
As como se puede leer y escribir datos simples, tambin se pueden leer y escribir datos estructurados. El esquema es el mismo, basta con especificar el tamao correcto.
Archivos binarios
struct pokemon{ char nombre[12]; int tipo; //0: fuego, 1:planta, //2:agua, 3:electrico double fuerza; double energia; };
Archivos binarios
void escribir(FILE* archivo){ archivo = fopen("test6.dat","w+b"); if(archivo!=NULL){ int i,k; struct pokemon pk1, pk2, pk3; strcpy(pk1.nombre,"pikachu"); pk1.tipo=3; pk1.fuerza=120; pk1.energia=87; fwrite(&pk1,sizeof(struct pokemon),1,archivo); fwrite(&pk2,sizeof(struct pokemon),1,archivo); fwrite(&pk3,sizeof(struct pokemon),1,archivo); fclose(archivo); } }
Archivos binarios
void escribir(FILE* archivo){ archivo = fopen("test6.dat","w+b"); if(archivo!=NULL){ int i,k; size_t wb; struct pokemon pk[3]; strcpy(pk[0].nombre,"pikachu"); pk[0].tipo=3; pk[0].fuerza=120; pk[0].energia=87;
wb = fwrite(pk,sizeof(struct pokemon),3,archivo); printf("%d bytes escritos en %d elementos\n", wb*sizeof(struct pokemon), wb); fclose(archivo); }
Archivos binarios
void leer(FILE* archivo){ printf("Leyendo\n"); archivo = fopen("test6.dat","r+b"); if(archivo!=NULL){ int i; struct pokemon pk; while(fread(&pk,sizeof(struct pokemon),1,archivo)==1){ printf("%s\n",pk.nombre); } fclose(archivo); } }
Archivos binarios
En archivos binarios ya no es necesario realizar accesos secuenciales. Es muy natural realizar accesos a estructuras de datos especificas, tanto para lectura como para escritura.
Archivos binarios
fseek
Mueve el cursor de lectura escritura a una posicin especifica del archivo int fseek(FILE* f, long nbytes, int origen);
Descriptor de archivo
Archivos binarios
fseek
Origen:
SEEK_SET: Principio del archivo SEEK_CUR: Posicin actual SEEK_END: Fin del archivo
Archivos binarios
ftell
Indica la posicin actual en el archivo (bytes respecto al inicio) long int ftell(FILE* f);
Descriptor de archivo
Archivos binarios
void leern(FILE* archivo, int n){ printf("Leyendo %d\n",n); archivo = fopen("test6.dat","r+b"); if(archivo!=NULL){ int i; struct pokemon pk; fseek(archivo, n*sizeof(struct pokemon),SEEK_SET); fread(&pk,sizeof(struct pokemon),1,archivo); printf("%s\n",pk.nombre); fclose(archivo); } }
Archivos binarios
void leerrev(FILE* archivo){ archivo = fopen("test6.dat","r+b"); if(archivo!=NULL){ int i; struct pokemon pk; fseek(archivo,-1*sizeof(struct pokemon),SEEK_END); while(fread(&pk,sizeof(struct pokemon),1,archivo)==1){ printf("%s\n",pk.nombre); fseek(archivo,-2*sizeof(struct pokemon),SEEK_CUR); } fclose(archivo); } }