procesamiento de archivos

54
Procesamiento de archivos Clase 12

Upload: tensor

Post on 16-Apr-2017

61 views

Category:

Education


0 download

TRANSCRIPT

Page 1: Procesamiento de archivos

Procesamientode archivos

Clase 12

Page 2: Procesamiento de archivos

Procesamientode archivos

• El almacenamiento de datos en variables y arreglos es temporal. Los archivos se utilizan para la persistencia de los datos: datos de retención permanente. Las computadoras almacenan archivos en dispositivos de almacenamiento secundario como discos duros, CDs, DVDs, unidades flash y cintas magnéticas. Explicaremos cómo construir programas en C++ para crear, actualizar y procesar archivos de datos.

Page 3: Procesamiento de archivos

Procesamientode archivos

• Consideraremos los archivos secuenciales y los archivos de acceso aleatorio. Compararemos el procesamiento de archivos de datos con formato y el procesamiento de archivos de datos puros. Examinaremos las técnicas para introducir datos de, y enviar datos a f lujos string en vez de archivos en el capítulo 18, La clase string y el procesamiento de f lujos de cadena.

Page 4: Procesamiento de archivos

Procesamientode archivos

• Consideraremos los archivos secuenciales y los archivos de acceso aleatorio. Compararemos el procesamiento de archivos de datos con formato y el procesamiento de archivos de datos puros. Examinaremos las técnicas para introducir datos de, y enviar datos a f lujos string en vez de archivos en el capítulo 18, La clase string y el procesamiento de f lujos de cadena.

Page 5: Procesamiento de archivos

Jerarquía de datos

• Finalmente, todos los elementos de datos que procesan las computadoras digitales se reducen a combinaciones de ceros y unos. Esto ocurre debido a que es simple y económico construir dispositivos electrónicos que puedan asumir uno de dos estados estables: un estado representa 0 y el otro representa 1. Es increíble que las impresionantes funciones realizadas por las computadoras impliquen solamente las manipulaciones más fundamentales de 0s y 1s.

Page 6: Procesamiento de archivos

Jerarquía de datos

• El elemento más pequeño de datos que soportan las computadoras se conoce como bit (abreviatura de “dígito binario”; un dígito que puede suponer uno de dos valores).. Cada elemento de datos, o bit, puede asumir el valor 0 o el valor 1Los circuitos de computadora realizan varias manipulaciones simples de bits, como examinar o establecer el valor de un bit, o invertir su valor (de 1 a 0 o de 0 a 1).

Page 7: Procesamiento de archivos

Jerarquía de datos

• Es muy difícil para los programadores trabajar con datos en el formato de bits de bajo nivel. Es preferible trabajar con datos en formatos como dígitos decimales (0-9), letras (A-Z y a-z) y símbolos especiales ( por ejemplo, $, @, %, &, * y muchos otros). Los dígitos, letras y símbolos especiales se conocen como caracteres. El conjunto de caracteres de una computadora es el conjunto de todos los caracteres utilizados para escribir programas y representar elementos de datos de esa computadora.

Page 8: Procesamiento de archivos

Jerarquía de datos

• Las computadoras pueden procesar solamente 1s y 0s, por lo que cada carácter en el conjunto de caracteres de una computadora se representa como un patrón de 1s y 0s. Los bytes están compuestos de ocho bits. Los programadores crean programas y elementos de datos con caracteres; las computadoras manipulan y procesan estos caracteres como patrones de bits. Por ejemplo, C++ proporciona el tipo de datos char.

Page 9: Procesamiento de archivos

Jerarquía de datos

• Cada char por lo general ocupa un byte. C++ también proporciona el tipo de datos wchar_t, que puede ocupar más de un byte ( para soportar conjuntos de caracteres más grandes, como el conjunto de caracteres Unicode®; para obtener más información acerca de Unicode®, visite el sitio www.unicode.org).

Page 10: Procesamiento de archivos

Jerarquía de datos

• Así como los caracteres están compuestos de bits, los campos están compuestos de caracteres. Un campo es un grupo de caracteres que transmiten cierto significado. Por ejemplo, un campo que consiste de letras mayúsculas y minúsculas puede representar el nombre de una persona.

• Los elementos de datos que son procesados por las computadoras forman una jerarquía de datos (figura 1), en la cual los elementos de datos se hacen más grandes y complejos en estructura, a medida que progresamos de bits a caracteres, de caracteres a campos, hacia agregados de datos más grandes.

Page 11: Procesamiento de archivos

Jerarquía de datos

Page 12: Procesamiento de archivos

Jerarquía de datos

• Generalmente, un registro (que puede ser representado como una clase en C++) está compuesto de varios campos (conocidos como miembros de datos en C++). Por ejemplo, en un sistema de nóminas el registro para un empleado específico podría incluir los siguientes campos:

• 1. Número de identificación del empleado

• 2. Nombre

• 3. Dirección

Page 13: Procesamiento de archivos

Jerarquía de datos

• 4. Sueldo por hora

• 5. Número de exenciones reclamadas

• 6. Ingresos desde inicio de año a la fecha

• 7. Monto de impuestos retenidos

Page 14: Procesamiento de archivos

Jerarquía de datos

• Por lo tanto, un registro es un grupo de campos relacionados. En el ejemplo anterior, cada campo está asociado al mismo empleado. Un archivo es un grupo de registros relacionados. El archivo de nómina de una compañía generalmente contiene un registro para cada empleado. Por ejemplo, un archivo de nómina para una pequeña compañía podría contener sólo 22 registros, mientras que un archivo de nómina para una compañía grande podría contener 100,000 registros. Es común para una compañía tener muchos archivos, algunos de ellos conteniendo miles de millones, o incluso billones de caracteres de información

Page 15: Procesamiento de archivos

Jerarquía de datos

• Para facilitar la recuperación de registros específicos de un archivo, debe seleccionarse cuando menos un campo en cada registro como clave de registro. Una clave de registro sirve para identificar que un registro pertenece a una persona o entidad específica, y es única en cada registro. En el registro de nómina que describimos anteriormente, por lo general se elegiría el número de identificación de empleado como clave de registro.

Page 16: Procesamiento de archivos

Jerarquía de datos

• Existen muchas formas de organizar los registros en un archivo. Un tipo común de organización se conoce como archivo secuencial, en el cual los registros se almacenan en orden, con base en el campo que es la clave de registro. En un archivo de nómina, los registros generalmente se colocan en orden, con base en el número de identificación de empleado. El registro del primer empleado en el archivo contiene el número de identificación de empleado más pequeño, y los registros subsiguientes contienen números cada vez mayores.

Page 17: Procesamiento de archivos

Jerarquía de datos

• La mayoría de las empresas utilizan muchos archivos distintos para almacenar datos. Por ejemplo, una compañía podría tener archivos de nómina, de cuentas por cobrar (listas del dinero que deben los clientes), de cuentas por pagar (listas del dinero que se debe a los proveedores), archivos de inventarios (listas de información acerca de los artículos que maneja la empresa) y muchos otros tipos de archivos. A menudo, un grupo de archivos relacionados se almacena en una base de datos. A una colección de programas diseñada para crear y administrar bases de datos se le conoce como sistema de administración de bases de datos (DBMS).

Page 18: Procesamiento de archivos

Archivos y flujos

• C++ considera a cada archivo como una secuencia de bytes (figura 2). Cada archivo termina con un marcador de fin de archivo o con un número de bytes específico que se registra en una estructura de datos administrativa, mantenida por el sistema. Cuando se abre un archivo, se crea un objeto y se asocia un flujo a ese objeto. Vimos que los objetos cin, cout, cerr y clog se crean cuando se incluye <iostream>. Los flujos asociados con estos objetos proporcionan canales de comunicación entre un programa y un archivo o dispositivo específico.

Page 19: Procesamiento de archivos

Archivos y flujos

• Por ejemplo, el objeto cin (objeto flujo de entrada estándar) permite a un programa introducir datos desde el teclado o desde otros dispositivos, el objeto cout (objeto flujo de salida estándar) permite a un programa enviar datos a la pantalla o a otros dispositivos, y los objetos cerr y clog (objetos flujo de error estándar) permiten a un programa enviar mensajes de error a la pantalla o a otros dispositivos.

Page 20: Procesamiento de archivos

Archivos y flujos

Page 21: Procesamiento de archivos

Archivos y flujos

• Para llevar a cabo el procesamiento de archivos en C++, se deben incluir los archivos de encabezado <iostream> y <fstream>. El encabezado <fstream> incluye las definiciones para las plantillas de clases de flujos basic_ ifstream ( para las operaciones de entrada con archivos), basic_ofstream ( para las operaciones de salida con archivos) y basic_fstream ( para las operaciones de entrada y salida con archivos). Cada plantilla de clase tiene una especialización de plantilla predefi nida que permite las operaciones de E/S con valores char.

Page 22: Procesamiento de archivos

Archivos y flujos

• Además, la biblioteca <fstream> proporciona alias typedef para estas especializaciones de plantilla. Por ejemplo, la definición typedef istream representa a una especialización de basic_ifstream que permite la entrada de valores char desde un archivo. De manera similar, typedef ofstream representa una especialización de basic_ofstream que permite enviar valores char a archivos. Además, typedf fstream representa una especialización de basic_fstream que permite introducir valores char desde (y enviarlos hacia) archivos.

Page 23: Procesamiento de archivos

Archivos y flujos

• Para abrir los archivos, se crean objetos de estas especializaciones de plantillas de flujo. Estas plantillas se “derivan” de las plantillas de clases basic_istream, basic_ostream y basic_iostream, respectivamente. Por ende, todas las funciones miembro, operadores y manipuladores que pertenecen a estas plantillas también se pueden aplicar a los flujos de archivos. En la figura 3 se sintetizan las relaciones de herencia de las clases de E/S que hemos visto hasta este punto.

Page 24: Procesamiento de archivos

Archivos y flujos

Page 25: Procesamiento de archivos

Creación de un archivo secuencial

• C++ no impone una estructura sobre un archivo. Por ende, en un archivo de C++ no existe un concepto tal como el de un “registro”. En consecuencia, el programador debe estructurar los archivos de manera que cumplan con los requerimientos de la aplicación. En el siguiente ejemplo veremos cómo se puede imponer una estructura de registro simple sobre un archivo.

Page 26: Procesamiento de archivos

Creación de un archivo secuencial

• La figura 4 crea un archivo secuencial que podría utilizarse en un archivo de cuentas por cobrar, para ayudar a administrar el dinero que deben los clientes de crédito a una empresa. Para cada cliente, el programa obtiene su número de cuenta, nombre y saldo (es decir, el monto que el cliente debe a la empresa por los bienes y servicios recibidos en el pasado).

Page 27: Procesamiento de archivos

Creación de un archivo secuencial

• Los datos que se obtienen para cada cliente constituyen un registro para ese cliente. El número de cuenta sirve como la clave de registro; es decir, el programa crea y da mantenimiento al archivo en orden por número de cuenta.

Page 28: Procesamiento de archivos

Creación de un archivo secuencial

• Este programa supone que el usuario introduce los registros en orden por número de cuenta. En un sistema de cuentas por cobrar completo, sería conveniente contar con una herramienta para ordenar datos, para que el usuario pueda introducir los registros en cualquier orden; después los registros se ordenarían y escribirían en el archivo

Page 29: Procesamiento de archivos

Creación de un archivo secuencial

Page 30: Procesamiento de archivos

Creación de un archivo secuencial

• Vamos a examinar este programa. Como se dijo antes, para abrir los archivos se crean objetos ifstream, ofstream o fstream. En la figura 4, el archivo se va a abrir para salida, por lo que se crea un objeto ofstream. Se pasan dos argumentos al constructor del objeto: el nombre de archivo y el modo de apertura de archivo (línea 19).

Page 31: Procesamiento de archivos

Creación de un archivo secuencial

• Para un objeto ofstream, el modo de apertura de archivo puede ser ios::out para enviar datos a un archivo, o ios::app para adjuntar datos al final de un archivo (sin modificar los datos que ya estén en el archivo). Los archivos existentes que se abren con el modo ios::out se truncan: se descartan todos los datos en el archivo. Si el archivo especificado no existe todavía, entonces el objeto ofstream crea el archivo, usando ese nombre de archivo.

Page 32: Procesamiento de archivos

Creación de un archivo secuencial

• En la línea 19 se crea un objeto ofstream llamado archivoClientesSalida, asociado con el archivo clientes.

Page 33: Procesamiento de archivos

Creación de un archivo secuencial

• dat que se abre en modo de salida. Los argumentos "clientes.dat" e ios::out se pasan al constructor de ofstream, el cual abre el archivo (esto establece una “línea de comunicación” con el archivo). De manera predeterminada, los objetos ofstream se abren en modo de salida, por lo que en la línea 19 se podría haber utilizado la instrucción alterna ofstream archivoClientesSalida( "clientes.dat" ); para abrir clientes.dat en modo de salida.

Page 34: Procesamiento de archivos

Creación de un archivo secuencial

Page 35: Procesamiento de archivos

Creación de un archivo secuencial

• Después de crear un objeto ofstream y tratar de abrirlo, el programa prueba si la operación de apertura tuvo éxito.

• La instrucción if en las líneas 22 a 26 utiliza la función miembro operator! sobrecargada de ios para determinar si la operación open tuvo éxito. La condición devuelve un valor true si se establece el bit failbit o el bit badbit para el flujo en la operación open. Ciertos posibles errores son: tratar de abrir un archivo no existente en modo de lectura, tratar de abrir un archivo en modo de lectura o escritura sin permiso, y abrir un archivo en modo de escritura cuando no hay espacio disponible en disco.

Page 36: Procesamiento de archivos

Creación de un archivo secuencial

• Si la condición indica un intento fallido de abrir el archivo, en la línea 24 se imprime el mensaje de error "No se pudo abrir el archivo", y en la línea 25 se invoca a la función exit para terminar el programa. El argumento para exit se devuelve al entorno desde el que se invocó el programa. El argumento 0 indica que el programa terminó en forma normal; cualquier otro valor indica que el programa terminó debido a un error. El entorno de llamada ( probablemente el sistema operativo) utiliza el valor devuelto por exit para responder al error en forma apropiada.

Page 37: Procesamiento de archivos

Creación de un archivo secuencial

• Otra función miembro de operador sobrecargada de ios (operator void*) convierte el f lujo en un apuntador, para que se pueda evaluar como 0 (es decir, el apuntador nulo) o un número distinto de cero (es decir, cualquier otro valor de apuntador). Cuando se usa el valor de un apuntador como una condición, C++ convierte un apuntador nulo en el valor bool false y un apuntador no nulo en el valor bool true. Si se establecieron los bits failbit o badbit (vea el capítulo 15) para el f lujo, se devuelve 0 (false).

Page 38: Procesamiento de archivos

Creación de un archivo secuencial

• La condición en la instrucción while de las líneas 36 a 40 invoca a la función miembro operator void* en cin de manera implícita. La condición permanece como true, siempre y cuando no se haya establecido el bit failbit o el bit badbit para cin. Al introducir el indicador de fi n de archivo se establece el bit failbit para cin. La función operator void * se puede utilizar para probar un objeto de entrada para el fi n de archivo, en vez de llamar a la función miembro eof de manera explícita en el objeto de entrada .

Page 39: Procesamiento de archivos

Creación de un archivo secuencial

• Si en la línea 19 se abrió el archivo con éxito, el programa empieza a procesar los datos. En las líneas 28 y 29 se pide al usuario que introduzca varios campos para cada registro, o el indicador de fi n de archivo cuando esté completa la entrada de datos. En la figura 6 se listan las combinaciones de teclado para introducir el fin de archivo en varios sistemas computacionales.

Page 40: Procesamiento de archivos

Creación de un archivo secuencial

Page 41: Procesamiento de archivos

Creación de un archivo secuencial

• En la línea 36 se extrae cada conjunto de datos y se determina si se introdujo el fi n de archivo. Al encontrar el fi n de archivo, o cuando se introducen datos incorrectos, operator void * devuelve el apuntador nulo (que se convierte en el valor bool false) y la instrucción while termina. El usuario introduce el fin de archivo para informar al programa que ya no procese más datos. El indicador de fin de archivo se establece cuando el usuario introduce la combinación de teclas de fin de archivo. La instrucción while itera hasta que se establece el indicador de fi n de archivo.

Page 42: Procesamiento de archivos

Creación de un archivo secuencial

• En la línea 38 se escribe un conjunto de datos en el archivo clientes.dat, usando el operador de inserción de flujo << y el objeto archivoClientesSalida asociado con el archivo al principio del programa. Los datos se pueden recuperar mediante un programa diseñado para leer el archivo.

Page 43: Procesamiento de archivos

Creación de un archivo secuencial

• Observe que, debido a que el archivo creado en la figura 4 es simplemente un archivo de texto, puede verse en cualquier editor de texto. Una vez que el usuario introduce el indicador de fin de archivo, main termina. Esto invoca de manera implícita a la función destructor del objeto archivoClientesSalida, que cierra el archivo clientes.dat. También podemos cerrar el objeto ofstream de manera explícita, usando la función miembro close en la instrucción archivoClientesSalida.close();

Page 44: Procesamiento de archivos

Funciones miembro get y getline

• La función miembro get sin argumentos recibe como entrada un carácter del flujo designado (incluyendo caracteres de espacio en blanco y otros caracteres no gráficos, como la secuencia de teclas que representa el fin de archivo) y lo devuelve como el valor de la llamada a la función.

Page 45: Procesamiento de archivos

Uso de las funciones miembro eof, get y put

• La figura 4 demuestra el uso de las funciones miembro eof y get en el f lujo de entrada cin, y la función miembro put en el flujo de salida cout. El programa primero imprime el valor de cin.eof() [es decir, false (0 en la salida)] para mostrar que no ha ocurrido el fi n de archivo en cin. El usuario introduce una línea de texto y oprime Intro seguido del fin de archivo (<Ctrl>-z en sistemas Microsoft Windows, <Ctrl>-d en sistemas UNIX y Macintosh)

Page 46: Procesamiento de archivos

Uso de las funciones miembro eof, get y put

Page 47: Procesamiento de archivos

Uso de las funciones miembro eof, get y put

Page 48: Procesamiento de archivos

Comparación entre cin y cin.get

• La figura 5 compara la entrada mediante el uso de la extracción de flujo con cin (que lee caracteres hasta que se encuentra un carácter de espacio en blanco) y la entrada mediante el uso de cin.get. Observe que la llamada a cin.get (línea 24) no especifica un delimitador, por lo que se utiliza el carácter predeterminado '\n'.

Page 49: Procesamiento de archivos

Comparación entre cin y cin.get

• La figura 5 compara la entrada mediante el uso de la extracción de flujo con cin (que lee caracteres hasta que se encuentra un carácter de espacio en blanco) y la entrada mediante el uso de cin.get. Observe que la llamada a cin.get (línea 24) no especifica un delimitador, por lo que se utiliza el carácter predeterminado '\n'.

Page 50: Procesamiento de archivos

Comparación entre cin y cin.get

Page 51: Procesamiento de archivos

Comparación entre cin y cin.get

Page 52: Procesamiento de archivos

Uso de la función miembro getline

• La función miembro getline opera de manera similar a la tercera versión de la función miembro get e inserta un carácter nulo después de la línea en el arreglo de caracteres. La función getline elimina el delimitador del f lujo (es decir, lee el carácter y lo descarta), pero no lo almacena en el arreglo de caracteres. El programa de la fi gura 15.6 demuestra el uso de la función miembro getline para introducir una línea de texto (línea 15).

Page 53: Procesamiento de archivos

Uso de la función miembro getline

Page 54: Procesamiento de archivos

Uso de la función miembro getline