8
Laboratorio de Programación II Página 23 Mgter. Ángel Montesinos, M. Sc. Carlo Corrales Sesión N° 04 NIVERSIDAD CATÓLICA DE SANTA MARÍA PROGRAMA PROFESIONAL DE INGENIERÍA DE SISTEMAS SESIÓN 04: Gestión de Archivos en C++ I OBJETIVOS Conocer las ventajas, diferencias y características en la utilización de tipos de datos estructurados. Aprender a declarar, usar y estructuras datos con clases y estructuras. Apreciar y valorar los recursos de las estructuras y clases para la programación de aplicaciones. II TEMAS A TRATAR Introducción. ¿Qué es un archivo de acceso secuencial?. ¿Qué es un archivo de acceso aleatorio? Operaciones con archivos secuenciales y aleatorios Archivos de acceso directo Resumen III MARCO TEORICO 1. INTRODUCCIÓN Los datos ingresados a un programa en ejecución se guardan o almacenan en variables, luego estas variables realizan operaciones de diferente índole y producen información, al acabar la ejecución de un programa los datos almacenados en variables que están registradas en memoria se eliminan, los datos almacenados en las variables también son destruidos con ellas, para que se pueda preservar el valor de las variables al cierre del programa debemos almacenar dichos valores en un medio que nos permita recupera dichas variables después, este recurso es conocido como archivos o ficheros. Los Archivos o ficheros son estructuras de almacenamiento que se guardan en disco en lugar de en memoria, la ventaja es que dichos recursos no son destruidos con la finalización del programa. Un archivo pertenece a dos tipos básicos los binarios y los de texto, un archivo en si es un conjunto estructurado de datos, cuando se almacenan bajo una estructura, están compuestos de registros que es cada línea de información y los registros se componen de campos que es cada dato en la fila. Los archivos binarios se gestionan como archivos de acceso secuencial y de acceso directo o aleatorio, en los dos casos el almacenamiento de la información se hace mediante datos estructurados tipo registro, la diferencia del procesamiento es cómo se recorre el archivo, ya que bajo el modo secuencial se hace de registro en registro, en cambio bajo el modo aleatorio o de acceso directo se puede saltar un grupo o conjunto de registros a la vez, pero para que esta operación pueda funcionar los registros deben ser todas estructuras uniformes de la misma extensión.

Guía de Prácticas de Programación II Sesión 04 2014

Embed Size (px)

Citation preview

Page 1: Guía de Prácticas de Programación II Sesión 04 2014

Laboratorio de Programación II Página 23

Mgter. Ángel Montesinos, M. Sc. Carlo Corrales Sesión N° 04

NIVERSIDAD CATÓLICA DE SANTA MARÍA PROGRAMA PROFESIONAL DE INGENIERÍA DE SISTEMAS

SESIÓN N° 04:

Gestión de Archivos en C++

I

OBJETIVOS

Conocer las ventajas, diferencias y características en la utilización de tipos de datos estructurados.

Aprender a declarar, usar y estructuras datos con clases y estructuras. Apreciar y valorar los recursos de las estructuras y clases para la programación de

aplicaciones.

II

TEMAS A TRATAR

Introducción. ¿Qué es un archivo de acceso secuencial?. ¿Qué es un archivo de acceso aleatorio? Operaciones con archivos secuenciales y aleatorios Archivos de acceso directo Resumen

III

MARCO TEORICO

1. INTRODUCCIÓN

Los datos ingresados a un programa en ejecución se guardan o almacenan en variables, luego estas variables realizan operaciones de diferente índole y producen información, al acabar la ejecución de un programa los datos almacenados en variables que están registradas en memoria se eliminan, los datos almacenados en las variables también son destruidos con ellas, para que se pueda preservar el valor de las variables al cierre del programa debemos almacenar dichos valores en un medio que nos permita recupera dichas variables después, este recurso es conocido como archivos o ficheros.

Los Archivos o ficheros son estructuras de almacenamiento que se guardan en disco en lugar de en memoria, la ventaja es que dichos recursos no son destruidos con la finalización del programa. Un archivo pertenece a dos tipos básicos los binarios y los de texto, un archivo en si es un conjunto estructurado de datos, cuando se almacenan bajo una estructura, están compuestos de registros que es cada línea de información y los registros se componen de campos que es cada dato en la fila. Los archivos binarios se gestionan como archivos de acceso secuencial y de acceso directo o aleatorio, en los dos casos el almacenamiento de la información se hace mediante datos estructurados tipo registro, la diferencia del procesamiento es cómo se recorre el archivo, ya que bajo el modo secuencial se hace de registro en registro, en cambio bajo el modo aleatorio o de acceso directo se puede saltar un grupo o conjunto de registros a la vez, pero para que esta operación pueda funcionar los registros deben ser todas estructuras uniformes de la misma extensión.

Page 2: Guía de Prácticas de Programación II Sesión 04 2014

Laboratorio de Programación II Página 24

Mgter. Ángel Montesinos, M. Sc. Carlo Corrales Sesión N° 04

La gestión de archivos de acceso directo se asemeja a la forma profesional en que en la actualidad los sistemas de información procesan el almacenamiento de la información.

2. ¿QUÉ ES UN ARCHIVO DE ACCESO SECUENCIAL?

Un archivo de acceso secuencial es aquel que se procesa saltando de registro en registro uno a la vez, los archivos se procesan de forma secuencial generalmente cuando se hacen procesos de consolidación o procesos batch. Se requiere visitar cada uno de los registros en una secuencia ordenada, el hacer una búsqueda secuencial de un registro en un archivo puede ser un proceso muy lento, más aun sí el archivo es muy grande, cuando se requiere mayor velocidad de búsqueda se hacen uso de otro tipo de estrategias que no son secuenciales.

3. ¿QUÉ ES UN ARCHIVO DE ACCESO ALEATORIO?

Los archivos de acceso aleatorio a diferencia de los anteriores tienen la capacidad de saltar de un registro a otro sin que exista la necesidad de que los registros estén uno tras otro o sean contiguos. Este proceso se hace a través de una función que permite hacer esos saltos. Bajo el uso de este mecanismo se puede saltar a un registro determinado teniendo como base de salto el principio del archivo, el registro actual o el final del archivo, los archivos de acceso secuencial se gestionan para ahorra tiempo de acceso en la búsqueda de la información, se descuenta que el ordenamiento de los registros es necesario para poder optimizar la búsqueda.

En Lenguaje C++ al almacenar registros representados por structs se crean los archivos bajo formato ya sea binario o de texto, los archivos no son creados como archivos secuenciales o de acceso aleatorio, en cambio la forma como estos son procesados les da dicha característica.

4. OPERACIONES CON ARCHIVOS SECUENCIALES Y

ALEATORIOS

La creación de archivos de acceso secuencial y aleatorio es tan igual como en los archivos de otro tipo, tal vez la única diferencia es especificar que el formato de creación es binario:

// Fig. 4.1: fig04_01.cpp

// Crea un archivo de formato binario para escritura.

#include <iostream>

using namespace std;

int main()

{

//define un apuntador a archivo

FILE *ptrArchivo1;

//se crea el archivo la direccion queda en el puntero

ptrArchivo1 = fopen("c:\\carpeta\\texto.txt","wb");

if (ptrArchivo1 == 0)

{

//si la creación falla se termina el programa

cout << "ERROR: No se pudo crear el archivo. . . " << endl;

system("pause");

exit(0);

}

else

//mensaje de creación exitosa

cout << "Archivo se creo exitosamente " << endl;

//cerrar el archivo

Page 3: Guía de Prácticas de Programación II Sesión 04 2014

Laboratorio de Programación II Página 25

Mgter. Ángel Montesinos, M. Sc. Carlo Corrales Sesión N° 04

fclose(ptrArchivo1);

system("pause");

return 0;

}

A. GRABACIÓN Y LECTURA EN DISCO

Como ya se mencionó grabar y leer registros o estructuras a renglones o registros de archivos en disco se hace mediante el uso de ciertas funciones. Estos dos procesos son los casos más comunes y frecuentes que se pueden realizar con un archivo de disco.

// Fig. 4.2: fig04_02.cpp

// Abre un archivo de formato binario para agregar productos.

#include <iostream>

using namespace std;

struct Producto

{

int codigo;

char nombre[30];

int cantidad;

float precio;

};

int main()

{

//define un apuntador a archivo

FILE *ptrArchivo1;

Producto varProducto;

char resp = ' ';

//se crea el archivo la direccion queda en el puntero

ptrArchivo1 = fopen("c:\\carpeta\\producto.dat","ab");

if (ptrArchivo1 == 0)

{

//si la creación falla se termina el programa

cout << "ERROR: No se pudo crear el archivo. . . " << endl;

system("pause");

exit(0);

}

else

//mensaje de creación exitosa

cout << "Archivo se creó exitosamente " << endl;

system("pause");

do{

//ingresar datos a estructura

system("cls");

cout << "\t INGRESO DE PRODUCTOS " << endl;

cout << "\t ==================== " << endl << endl;

cout << "Codigo de Producto: ";

cin >> varProducto.codigo;

cout << "Nombre de Producto: ";

fflush(stdin);

gets(varProducto.nombre);

cout << "Cantidad de Producto: ";

cin >> varProducto.cantidad;

cout << "Precio de Producto: ";

cin >> varProducto.precio;

// grabar el registro en el archivo

fwrite(&varProducto, sizeof(Producto), 1, ptrArchivo1);

// preguntar si desea agregar otro registro

do{

cout << endl << endl << "Desea ingresar otro producto? (S/N): ";

cin >> resp;

resp = toupper(resp);

}while(resp != 'S' && resp != 'N');

}while(resp != 'N');

Page 4: Guía de Prácticas de Programación II Sesión 04 2014

Laboratorio de Programación II Página 26

Mgter. Ángel Montesinos, M. Sc. Carlo Corrales Sesión N° 04

// cerrar el archivo

fclose(ptrArchivo1);

system("pause");

return 0;

}

La primera observación es que se usa la función fopen() en modo "at+" en lugar de modo "w". La única instrucción nueva es:

fwrite(&varProducto, sizeof(Producto), 1, ptrArchivo1);

Como se observa tiene cuatro parámetros que son:

Como primer parámetro se coloca la dirección del registro que se va a grabar en el archivo, en este caso de la variable varProducto.

En un segundo parámetro se debe especificar la cantidad de espacio en bytes que ocupará en el archivo, se puede hacer de form explícita o de lo contrario con el operador sizeof().

Para el tercer parametro se especifica el número de registros que se van a grabar en el archivo, en este caso uno, pero se puede grabar un número mayor de registros a la vez.

El último parámetro es para especificar la dirección en disc donde se almaceará los registros, en este caso se usa el puntero a archivo ptrArchivo1.

// Fig. 4.3: fig04_03.cpp

// Crea un archivo de formato binario para leer los registros almacenados.

#include <iostream>

using namespace std;

struct Producto

{

int codigo;

char nombre[30];

int cantidad;

float precio;

};

int main()

{

//define un apuntador a archivo

FILE *ptrArchivo1;

Producto varProducto;

char resp = ' ';

//se crea el archivo la direccion queda en el puntero

ptrArchivo1 = fopen("c:\\carpeta\\producto.dat","ab+");

if (ptrArchivo1 == 0)

{

//si la creación falla se termina el programa

cout << "ERROR: No se pudo crear el archivo. . . " << endl;

system("pause");

exit(0);

}

else

//mensaje de creación exitosa

cout << "Archivo se creo exitosamente " << endl;

system("pause");

// leer el registro del archivo

while(fread(&varProducto,sizeof(varProducto),1,ptrArchivo1) == 1)

{

system("cls");

cout << "\t LISTA DE PRODUCTOS " << endl;

cout << "\t ================== " << endl << endl;

cout << "Codigo de Producto: " << varProducto.codigo << endl;

cout << "Nombre de Producto: " << varProducto.nombre << endl;

cout << "Cantidad de Producto: " << varProducto.cantidad << endl;

cout << "Precio de Producto: " << varProducto.precio << endl;

system("pause");

Page 5: Guía de Prácticas de Programación II Sesión 04 2014

Laboratorio de Programación II Página 27

Mgter. Ángel Montesinos, M. Sc. Carlo Corrales Sesión N° 04

}

// cerrar el archivo

fclose(ptrArchivo1);

system("pause");

return 0;

}

En fopen() se usó en modo "ab+". En lugar de fwrite(), se usa fread() con los mismos parámetros:

fread(&varProducto,sizeof(varProducto),1,ptrArchivo1);

La función fread(), devuelve el número de registros que leyó del disco, por eso el ciclo while se convierte en falso cuando fread() regresa 0 y esto indica que se llegó al final del archivo.

El procesamiento del archivo, tanto en la lectura y escritura se hizo de forma secuencial, la escritura de registros en el disco siempre tiende a ser secuencial. Por el contrario los archivos de acceso directo puede hacer la lectura de forma aleatoria y la edición de registros sería una actividad un tanto más compleja ya que requiere un proceso de lectura/escritura.

5. ARCHIVOS DE ACCESO DIRECTO

No se crea un archivo como de acceso secuencial o aleatorio, la forma como se gestiona éste es lo que le otorga esa característica, un archivo de acceso directo es cuando mediante algún mecanismo se direcciona directamente al registro sin necesidad de procesar otros registros previamente, para este tipo de proceso se hace uso de la función fseek() que nos permite directamente acceder a un registro n cualquiera. La función hace un procesamiento directo al saltar al registro que se quiere operar, por lo general es lectura únicamente, una vez terminado el proceso se debe de hacer retornar al puntero del archivo al principio.

// Fig. 4.4: fig04_04.cpp

// Crea un archivo de formato binario para lectura directa.

#include <iostream>

using namespace std;

struct Producto

{

int codigo;

char nombre[30];

int cantidad;

float precio;

};

int main()

{

//define un apuntador a archivo

FILE *ptrArchivo1;

Producto varProducto;

int numero = 0;

char resp = ' ';

//se crea el archivo la direccion queda en el puntero

ptrArchivo1 = fopen("c:\\carpeta\\producto.dat","ab+");

if (ptrArchivo1 == 0)

{

//si la creación falla se termina el programa

cout << "ERROR: No se pudo crear el archivo. . . " << endl;

system("pause");

exit(0);

}

else

Page 6: Guía de Prácticas de Programación II Sesión 04 2014

Laboratorio de Programación II Página 28

Mgter. Ángel Montesinos, M. Sc. Carlo Corrales Sesión N° 04

//mensaje de creación exitosa

cout << "Archivo se creo exitosamente " << endl;

system("pause");

// leer el registro del archivo

do{

system("cls");

cout << "Ingresar el numero de registro: " << endl;

cin >> numero;

fseek(ptrArchivo1,(long)(numero+1)* sizeof(varProducto), 0 );

fread(&varProducto,sizeof(varProducto),1,ptrArchivo1);

cout << "\t LISTA DE PRODUCTOS " << endl;

cout << "\t ================== " << endl << endl;

cout << "Codigo de Producto: " << varProducto.codigo << endl;

cout << "Nombre de Producto: " << varProducto.nombre << endl;

cout << "Cantidad de Producto: " << varProducto.cantidad << endl;

cout << "Precio de Producto: " << varProducto.precio << endl;

system("pause");

do{

cout << endl << endl << "Desea mostrar otro producto? (S/N): ";

cin >> resp;

resp = toupper(resp);

}while(resp != 'S' && resp != 'N');

}while(resp != 'N');

// cerrar el archivo

fclose(ptrArchivo1);

system("pause");

return 0;

}

Como se desprende del programa usando fseek() es posible posicionarse en cualquier byte del archivo, es necesario tener el criterio sobre los mecanismos exactos de calculo para que la lectura sea correcta. El formato completo de fseek() es:

fseek(ptrArchivo1,(long)(numero+1)* sizeof(varProducto), 0 );

Donde los parámetros son:

El primer parámetros es el apuntador al archivo en disco El segundo parámetro es el BYTE donde se quiere que empiece la lectura o

grabación al archivo en disco. Este BYTE debe ser de tipo LONG, se usa el operador sizeof o tamaño de registro para calcular la pocisión exacta.

El tercer parámetro es a partir de donde se quiere posicionar el apuntador interno del archivo, los valores pueden ser:

0 ---> SEEK_SET principio del archivo. 1 ---> SEEK_CUR posición actual.

2 ---> SEEK_END fin del archivo.

Se debe recordar que es muy importante que las claves grabadas en un archivo directo tengan la secuencia 0,1,2,3,4,5.....n.

A pesar de que la secuencia de registros se supone ordenada para que sea efectivo el uso de esta función, debemos tener en cuenta que no necesariamente todos los registros están presentes, por lo que, al faltar alguno no sabemos exactamente donde estará el registro buscado exactamente, eso se arregla usando estructuras de datos como árboles que mantienen un orden de los registros así como su posición real en el archivo.

6. RESUMEN

Los archivos en Lenguaje C++ se hace gestionan bajo dos tipos diferentes de estrategias, bajo una primera estrategia los registros son procesados uno por uno de una forma secuencial, por lo que a este tipo de archivos gestionados de esta forma se les denomina archivos secuenciales, los procesos en un archivo secuencial se hacen saltando de un registro al siguiente , iniciando el proceso desde el primero hasta llegar al archivo deseado

Page 7: Guía de Prácticas de Programación II Sesión 04 2014

Laboratorio de Programación II Página 29

Mgter. Ángel Montesinos, M. Sc. Carlo Corrales Sesión N° 04

o buscado, a pesar de ser un proceso largo y que consume muchos recursos igual se sabe exactamente la posición de procesamiento sin problemas, esto a pesar de que falte algún registro de todos los presentes posibles; bajo un segundo esquema se posee la capacidad de saltar a un registro determinado sin necesidad de pasar secuencialmente por todos los anteriores, a este tipo de procesamiento se le llama de acceso aleatorio, los archivos así procesados reciben la denominación de archivos de acceso directo a aleatorio, para lograr esto se hace uso de una función que nos permite saltar al Byte exacto que queremos leer, debemos tener en cuenta que se inicia por la posición 0, la única dificultad que muestra esta forma de procesamiento es la falta física de algún registro por lo que el salto no sería exacto lo que hará necesario la utilización de algún mecanismo para salvar esta inconveniente como el uso de estructuras de datos o la búsqueda binaria.

IV

(La práctica tiene una duración de 2 horas) ACTIVIDADES

1. Encender el equipo de cómputo, si existe algún desperfecto o faltante en el equipo comunicarlo inmediatamente.

2. Al aparecer la solicitud de contraseña hacer clic en el botón Cancelar o ingresar el nombre de cuenta(login) y contraseña(password) que especifique el Docente. Esperar que aparezca el mensaje de Inicio de sesión.

3. Ejecutar el Visual Studio 2010. 4. Crear una carpeta que se llame Programación II y dentro de ella una que se llame

Práctica Nº 04 dentro de la carpeta Mis Documentos. 5. Nombrar los proyectos como se indica en el archivo Actividades N° 04 que se adjunta y

asegurarse de almacenarlos en la carpeta Práctica Nº 04 al momento de crearlos. 6. Realizar las acciones indicadas en el archivo adjunto. 7. Al finalizar la práctica de be guardar todos sus archivos, ya sea en su memoria USB o por

correo electrónico y luego eliminar los archivos del equipo y vaciar la papelera de reciclaje.

V

EJERCICIOS

1. Elaborar programa en Lenguaje C++ que nos permita ingresar por teclado los datos de un producto y almacenarlos en un archivo.

2. Agregar funciones para búsqueda secuencial de productos en el archivo creado. 3. Agregar funciones para hacer búsqueda binaria usando mecanismos de acceso directo en

la búsqueda de un registro de un producto determinado en el archivo.

VI

CUESTIONARIO

1. ¿Qué es un proceso batch? 2. ¿Qué es un archivo de acceso secuencial? 3. ¿Qué es un archivo de acceso directo o aleatorio? 4. ¿Qué es un campo clave? 5. ¿Cuáles son las operaciones básicas que se pueden ejecutar sobre un archivo de acceso

secuencial? 6. ¿De cuántas formas se puede crear un archivo de acceso secuencial? 7. ¿De cuántas formas se puede abrir un archivo de acceso secuencial? 8. ¿Cómo se leen registros en un archivo de acceso secuencial? 9. ¿Qué diferencia existe entre la lectura secuencial y la directa de registros? 10. ¿Cómo se graban registros en archivos de acceso directo? 11. ¿Qué diferencia existe entre la escritura de registros secuencial y directa? 12. ¿Cómo se usa la forma append de creación o apertura de archivos de acceso directo? 13. ¿Cómo se usa la función fseek() para leer un registro? 14. ¿Dónde queda el puntero del archivo después de hacer uso de la función fseek() y leer

el registro?

Page 8: Guía de Prácticas de Programación II Sesión 04 2014

Laboratorio de Programación II Página 30

Mgter. Ángel Montesinos, M. Sc. Carlo Corrales Sesión N° 04

VII

BIBLIOGRAFIA Y REFERENCIAS

Deitel, Paul J., Deitel, Harvey M., "Cómo Programar en C++", 6ta Edición, Ed. Pearson Educación, México 2009.

Stroustrup, Bjarne, "El Lenguaje de Programación C++", 3ra Edición, Adisson Pearson Educación S.A., Madrid 2002.

Eckel, Bruce, "Thinking in C++", 2da Edición, Prentice Hall, 2000.