Archivos - Departamento de Informática

Anuncio
Departamento de Informática
Universidad Técnica Federico Santa María
Archivos
Programación de Computadores
Prof. Teddy Alfaro
¿qué es un archivo?
• Un archivo es una estructura de datos de un
mismo tipo, sean éstos simples o
estructurados. Un archivo se almacena en un
dispositivo secundario (diskette, disco duro,
cinta, etc), de manera que los datos contenidos
en un archivo antes, durante y después de un
procesamiento (ejecución de un programa) no
se pierden.
1
Usos de Archivos
• La entrada y salida estándar de datos
(teclado y pantalla) pueden ser reemplazado
por el uso de archivos.
• Los programas utilizan archivos para
comunicarse con el mundo exterior y con
otros programas.
Información Masiva
• Imaginemos que hacemos un programa que
requiere que se le ingresen una gran cantidad de
datos. Pensemos, si estamos haciendo las pruebas
al programa, por cada corrida debemos ingresar de
nuevo los datos.
• Por otra parte, pensemos, nos interesa que nos
muestre una gran cantidad de datos, ordenados y
con estadísticas. El mostrarlos por pantalla se
limita a mostrar sólo lo ultimo que queda en
pantalla
2
Leer información, guardar
información
Archivo
almacenado
en algún dispositivo
de memoria
secundaria
Flujo de
información, pueder
binario o de texto
Carga de datos en
memoria principal
para que puedan ser
usados por
programas
Proceso de escritura
archivo
archivo
flujo
Proceso de Lectura
flujo
Memoria
principal
Memoria
principal
Flujos
Flujos de Texto:
• Es una secuencia de caracteres.
• En un flujo de texto, pueden ocurrir ciertas conversiones
de caracteres si el entorno del sistema lo requiere.
• El número de bytes escritos y leídos puede no ser iguales.}
Flujos Binarios:
• Es una secuencia de bytes con una correspondencia de uno
a uno con los dispositivos externos.
• No se realizan conversiones de caracteres.
• El número de bytes escritos y leídos es el mismo.
3
Archivos para C
• La entrada y salida a archivos es un aspecto
dependiente del S.O. Las librerías de C proveen
un conjunto de funciones para trabajar con
archivos
• Se pueden distinguir 2 tipos de funciones de E/S,
las tipos Unix que trabajan sin buffer, y la estandar
ANSI que utilizan buffer intermedio (trabajaremos
con el sistema ANSI).
Sistema de Archivos ANSI C
• La librería stdio.h nos provee un cojunto de
funciones:
–
–
–
–
–
–
–
–
–
–
–
fopen( ): abrir un archivo
fclose( ): cerrar un archivo
fputc ( ): escribe un char en archivo
fgetc ( ): lee un char de un archivo
fseek ( ): busquede de byte
fprintf ( ): printf para archivos
fscanf ( ): scanf para archivos
feof ( ): indentificador de final de archivo
ferror ( ): devuelve 1 o 0 si hubo error en el flujo
rewind ( ): se posiciona al inicio del archivo
remove ( ): borra una archivo
4
Stream, FILE
• Las operaciones de un archivos se hacen a través
de un stream. Un stream es una serie ordenada de
byte (muchos bytes).
• Leer o escribir un archivo implica leer o escribir
un stream.
• Para asociar un stream con un archivo se crea un
puntero a una estructura FILE, la cual contiene la
información necesaria para interactuar con el S.O.
Sistema de archivos
• La lógica para trabajar con archivo será:
– Para lectura: abrir un archivo, leo la información y
luego se cierra el archivo
– Para escritura: abrir (crear) archivo, escribir la
información y luego cerrar el archivo.
• La inicializacion de un *FILE, o dicho en otras
palabras, la apertura de un flujo de archivo se hace
con la función fopen(archivo, modo). El cierre
del flujo se hace con fclose(archivo)
5
Apertura de archivo
• El prototipo de fopen es:
FILE *fopen(const char *nombre_archivo, const char *modo);
• Donde
– Nombre_archivo: es el archivo con el cual se
trabajará (path incluido).
– Modo: es el modo de acceso para el stream
Modos de Acceso
•
El modo indica si el archivo se abrirá, o si se creará, si es de texto o
binario. Los modo posibles para C son:
– r: sólo lectura. El archivo debe existir.
– w: se abre para escritura, se crea un archivo nuevo o se sobreescribe si ya
existe.
– a: añadir, se abre para escritura, el cursor se sitúa al final del archivo. Si el
archivo no existe, se crea.
– r+: lectura y escritura. El archivo debe existir.
– w+: lectura y escritura, se crea un archivo nuevo o se sobreescribe si ya
existe.
– a+: añadir, lectura y escritura, el cursor se sitúa al final del archivo. Si el
archivo no existe, se crea.
– t: tipo texto, si no se especifica "t" ni "b", se asume por defecto que es "t"
– b: tipo binario.
6
Ejemplo
FILE *a, *b, *c, *d;
main( ) {
a=fopen(“datos.txt”, “r”);
b=fopen(“nombres.dat”, “a+”);
c=fopen(“ipc.tex”, “rt”);
d=fopen(“c:/cambios.rtf”, “r+b”);
..........
}
Error al abrir un archivo
• Abrir una archivo (lectura, agregar) que no existe causa
un error. Esta situación puede ser facilmente detectada
de la siguiente forma:
FILE *arch;
If ((arch=fopen(nombre_archivo,modo))==NULL) {
printf(“no es posible leer %s”,nombre_archivo);
exit(1);
}
Sin no existe el archivo, la función fopen devuelve NULL
7
Cerrar un Archivo
• No se debe olvidar cerrar todos los archivos
abiertos. Al cerrar los archivos, se guardan
los datos que aún están en el buffer y
además actualiza algunos datos de la
cabecera del arch que mantiene el S.O.
Además, libera el archivo para que otros
programas puedan abrirlo.
Cerrando Archivos
• La función es fclose, y su prototipo es
int fclose(FILE
*archivo);
• Devuelve cero si no hay error, y EOF en
caso contrario.
• Ejemplo
FILE *arch;
arch=fopen(“deuda.grande”,”r”);
......
fclose(arch);
8
Trabanjando sobre archivos
• Las operaciones de lectura o escritura que
podemos realizar sobre los archivos son
funciones de la librería stdio.h que pueden
trabajar en base a:
– Caracteres (char)
– Lineas
– bloques
Función fgetc
• Lectura de sólo un carácter desde un
archivo, el prototipo de esta función es:
int fgetc(FILE
*archivo);
• El valor de retorno es un carácter leído
como un unsigned char convertido a int.
• Si al leer no hay un carácter disponible el
valor de retorno es EOF
9
Función fputc
• Escritura de sólo un carácter hacia un
archivo
int fputc(int carácter, FILE *archivo);
• El valor de retorno es el carácter escrito, si
la operación de escritura fue realizada, de
los contrario devuelve EOF.
• Los parámetros son el carácter convertido a
int y un puntero FILE al archivo
Función feof
• Prototipo
int feof(FILE *archivo);
• Función que se utiliza pqra comprobar si se ha
llegado a fin de archivo (end of file)
• En los archivos guardas datos de un mismo tipo ya
sean simple o estructuras, no tenemos información
de cuantos registros hay, la idea será ir realizando
lecturas consecutivas hasta que se llegue a final de
archivo
• El valor de retorno es 1 cuando se ha llegado a fin
de archivo, de los contrario el retorno es 0.
10
Función rewind
• Prototipo:
void rewind(FILE *archivo);
• Función rebobinar, sitúa el cursor de
lectura/escritura en el primer elemento del
archivo (la información que fue registrada
primero que todas)
Ejemplo 1
• Realizar un programa en el cual guarde en
un archivo la información introducida por el
usuario a través del teclado. Se termina la
introducción por el teclado con el carácter
$.
• Realizar un programa que lea lo
introducido.
11
Ejemplo 1
#include <stdio.h>
int main(){
FILE *Archivo;
char c;
if ((Archivo=fopen("datos.dat","w+"))==NULL){
printf("No se puede abrir el archivo");
return 1;
}
do{
c=getchar();
putc(c,Archivo);
}while(c!='$');
rewind(Archivo);
while(!feof(Archivo) ){
c=fgetc(Archivo);
printf("%c",c);
}
fclose(Archivo);
return 0;
}
Ejemplo 2
// Muestra dos veces el archivo.
#include <stdio.h>
int main()
{
FILE *arch;
arch = fopen("ejemplo1.c", "r");
while(!feof(arch)) fputc(fgetc(arch), stdout);
rewind(arch);
while(!feof(arch)) fputc(fgetc(arch), stdout);
fclose(arch);
getchar();
return 0;
}
12
fprintf( )
• Prototipo
int fprintf(FILE *archivo, const char *formato,...)
• Impresión en archivo, funciona de manera
similar que printf, pero no imprime la
información por pantalla (stdout) sino que
la salida es dirigida a un archivo
• El retorno es el numero de caracteres
enviados, si es negativo se produce un error
en la salida
fscanf( )
• Prototipo:
int fscanf(FILE *archivo, const char *formato,...)
• Ingreso de valores, funciona de manera
similar a scanf, con la diferencia que los
datos no son de teclado (stdin), sin que la
entrada se toma desde un archivo
• Retorna el número de datos asignado y EOF
si ocurrió un error
13
ejemplo
Programa Ingreso datos
Programa mustra información
#include <stdio.h>
FILE *arch;
#include <stdio.h>
FILE *inf;
int main(int argc, char *argv[]){
int i,n1,n2,n3;
arch=fopen("notas.dat","w");
for (i=0;i<5;i++){
printf("\nnotas alumno %d ",i);
printf("ingrese sus 3 notas");
scanf("%d %d %d",&n1,&n2,&n3);
fprintf(arch,"%d %d %d ",n1,n2,n3);
}
fclose(arch);
return 0;
}
int main(int argc, char *argv[]){
int i,n1,n2,n3;
inf=fopen("notas.dat","r");
i=0;
while(!feof(inf) ){
fscanf(inf, "%d %d %d", &n1, &n2, &n3);
printf("%d %d %d ",n1, n2, n3);
printf("alumno %d
prom=%f\n",i,(n1+n2+n3)/3.0);
i++;
}
fclose(inf);
return 0;
}
Función fflush
• Prototipo
int fflush(FILE
*archivo);
• Esta función fuerza la salida de los datos acumulados en el
buffer de salida del archivo. Para mejorar el manejo de
archivos se utilizan buffers (almacenes temporales de datos
en memoria) las operaciones de salida se hacen a través del
buffer, y sólo cuando el buffer se llena se realiza la
escritura en el disco y se vacía el buffer. En ocasiones nos
hace falta vaciar ese buffer de un modo manual.
• El valor de retorno es 0 en caso de éxito,y EOF en caso
contrario
14
Función fseek( )
• Prototipo
int fseek(FILE *archivo, long int desp, int origen);
• Función cuya utilidad es posicionar el cursor del
archivo para leer o escribir en un lugar deseado
• Retorna 0 en caso de éxito
• Parámetros: el archivo, el desplazamiento desp en
bytes
• El parametro de origen
– SEEK_SET:
– SEEK_CUR:
– SEEK_END:
comienzo de archivo
ubicación actual
fin de archivo
ftell( )
• Prototipo:
long int ftell(FILE
*archivo);
• Función para averiguar cuál es la posición
actual del cursor de lectura/escritura de un
archivo
• El retorno será la pasición o –1 si se produjo
un error
15
fgets()
• Prototipo
char *fgets(char *cadena,int n ,FILE *archivo);
•
•
•
•
Función para lectura de string (cadena de caracteres).
Lee: n-1 caracteres o hasta que encuentra salto de línea
Cuando encuentra salto de línea, este también es leído
Los parámetros son: la cadena a leer, número máximo
de caracteres a leer y el FILE.
• El valor de retorno es un puntero a la cadena leída en
caso de lectura correcta, de lo contrario retorna NULL
(ejemplo: hacer una lectura y es fin de archivo
fputs()
• Prototipo:
int fputs(const char *cadena,FILE *archivo);
• Función que escribe una cadena en un archivo. La
cadena es escrita sin el valor de retorno y sin el
carácter de finalización de string
• Parámetros: cadena a escribir, archivo
• El valor de retorno es un número positivo o EOF
en caso de error
16
Ejemplo
#include <stdio.h>
int main() {
char nombre[10]="datos.dat", linea[81];
FILE *arch;
arch = fopen( nombre, "r" );
printf( "archivo: %s -> ", nombre );
if ( arch ) printf( "existe (ABIERTO)\n" );
else { printf( "Error (NO ABIERTO)\n" );
return 1; }
printf( "La primera linea del archivo: %s\n\n", nombre );
printf( "%s\n", fgets(linea, 81, arch) );
if( !fclose(arch) ) printf( "\narchivo cerrado\n" );
else { printf( "\nError: archivo NO CERRADO\n" );
return 1; }
return 0;
}
Ejemplo
#include <stdio.h>
int main( ) {
char nombre[11]="datos2.dat";
FILE *arch;
arch = fopen( nombre, "w" );
printf( "archivo: %s -> ", nombre );
if( arch ) printf( "creado (ABIERTO)\n" );
else { printf( "Error (NO ABIERTO)\n" );
return 1; }
fputs( "Esto es un ejemplo usando \'fputs\'\n", arch );
if( !fclose(arch) ) printf( "\narchivo cerrado\n" );
else { printf( "\nError: arch NO CERRADO\n" );
return 1; }
return 0; }
17
Guardando registros
• Al trabajar con estructuras o arreglos de
estructuras, los más natural es guardar la
información en un archivo, para que una
vez terminado el programa la información
no se pierda, y pueda ser recuperada
nuevamente en cualquier momento.
• A continuación veremos algunas funciones
para trabajar con estructuras y archivos
fread( )
• Prototipo
size_t fread(void *ptr,size_t tamaño,
size_t nregistros, FILE *archivo);
• Función capaz de leer desde un archivo uno o varios
registros de la misma longitud a partir de una
dirección de memoria determinda
• El valor de retorno es el número de registros leídos
• Parámetros: una puntero a la memoria donde se
almacenarán, el tamaño de cada registro, el número
de registros a leer y el archivo de donde se lee
18
fwrite()
• Prototipo:
size_t fwrite(void *ptr, size_t tamaño,
size_T nregistros,FILE *archivo);
• Función que permite escribir en un archivo uno o varios
registros de una misma longitud almacenados a partir
de una dirección de memoria determinada
• El valor de retorno es el número de registros escritos
• Parámetros: una puntero a la memoria donde se
almacenarán los datos, el tamaño de cada registro, el
número de registros a escribir y el archivo de donde se
escribiran
#include <stdio.h>
struct computador {
char placa[20], procesador[20];
int memoria,velocidad,t_disco;
} stock[4]={ {"asus","intel p4",256, 2600,2} , {"msi","amd athlon", 512, 2800,80} ,
{"microstar", "celeron", 2400, 60} , {"A-open", "Septron", 3000, 120}
}, s;
FILE * arch;
int main(int argc, char *argv[]){
arch=fopen("computer.tex", "w+");
fwrite(&stock, sizeof(stock[0]),3,arch);
fwrite(&stock[3], sizeof(stock[3]), 1, arch);
rewind(arch);
printf("placa \t procesador \t memoria \t velocidad \t disco duro \n");
while(!feof(arch) ){
fread(&s, sizeof(s), 1, arch);
printf("%s\t\t%s\t\t%d\t\t%d\t\t%d\n", s.placa,
s.procesador,s.memoria,s.velocidad,s.t_disco);
}
fclose(arch);
return 0; }
19
#include <stdio.h>
struct computador {
char placa[20], procesador[20];
int memoria,velocidad,t_disco;
} s;
FILE * arch;
int main(int argc, char *argv[]){
arch=fopen("computer.tex", “r");
while( fread(&s,sizeof(s),1,arch) && !feof(arch) ) {
printf("%s\t\t%s\t\t%d\t\t%d\t\t%d\n", s.placa,
s.procesador,s.memoria,s.velocidad,s.t_disco);
}
fclose(arch);
return 0;
}
Creando un nuevo tipo: typedef
typedef float decimal;
typedef int* puntero;
typedef struct {
char nombre[20];
int edad;
float estatura,peso; } persona;
int main( ) {
decimal f; puntero k; persona p;
f=2.9;
k=(puntero)malloc(sizeof(int),1);
strcpy(p.nombre,”pedro”);
p.edad=44;
p.estatura=1.80;
p.peso=(decimal)85;
return 0;
}
struct persona {
char nombre[20];
int edad;
float estatura,peso;
};
int main( ) {
float f; int *k; struct persona p;
f=2.9;
k=(int *)malloc(sizeof(int),1);
strcpy(p.nombre,”pedro”);
p.edad=44;
p.estatura=1.80;
p.peso=(float)85;
return 0;
}
20
Descargar