Archivos y BD en C Sharp

26
Material preparado por Rodrigo Sandoval U en Mayo 2004 PONTIFICIA UNIVERSIDAD CATÓLICA DE CHILE ESCUELA DE INGENIERÍA DEPARTAMENTO DE CIENCIA DE LA COMPUTACIÓN IIC 1102 INTRODUCCIÓN A LA PROGRAMACIÓN Profesor: Rodrigo Sandoval U. Capítulo IX – Archivos en C# y Bases de Datos 1 LECTURA Y ESCRITURA DE ARCHIVOS DE TEXTO..................................................................................... 1 1.1 STREAMS ............................................................................................................................................................... 1 1.1.1 Lectura de Archivos ...................................................................................................................................... 1 1.2 USING SYSTEM.IO ................................................................................................................................................. 2 1.3 CONTROL DE ERRORES .......................................................................................................................................... 2 1.4 LECTURA: STREAMREADER................................................................................................................................... 2 1.4.1 Constructores de StreamReader.................................................................................................................... 2 1.4.2 Lectura con StreamReader ............................................................................................................................ 3 1.4.3 Ejemplo: Lectura de un Archivo de Texto, mostrando contenido en pantalla .............................................. 3 1.4.4 Ejemplo: Procesamiento de Operaciones Matemáticas en Archivo ............................................................. 4 1.5 ESCRITURA: STREAMWRITER ................................................................................................................................ 6 1.5.1 Constructores de StreamWriter ..................................................................................................................... 6 1.5.2 Escritura con StreamWriter .......................................................................................................................... 6 1.5.3 Ejemplo: Lectura y Escritura de un Archivo................................................................................................. 7 2 BASES DE DATOS................................................................................................................................................... 10 2.1 CONCEPTOS BÁSICOS DE BASES DE DATOS ......................................................................................................... 10 2.1.1 Base de Datos.............................................................................................................................................. 10 2.1.2 Sistema de Administración de Base de Datos ............................................................................................. 10 2.1.3 Elementos relacionados a una Base de Datos............................................................................................. 10 2.1.4 EJEMPLO ..................................................................................................................................................... 0 2.2 MODELOS DE BASES DE DATOS ........................................................................................................................... 12 2.2.1 Esquema de Archivos .................................................................................................................................. 12 2.2.2 Modelo Jerárquico ...................................................................................................................................... 12 2.2.3 Modelo Relacional ...................................................................................................................................... 13 2.2.4 Modelo Distribuido ..................................................................................................................................... 15 2.2.5 Modelo de BD Orientado a Objeto ............................................................................................................. 15 2.2.6 BD Multidimensional .................................................................................................................................. 15 2.3 PROGRAMACIÓN DE BASES DE DATOS CON C# .................................................................................................... 16 2.3.1 Ejemplo: Programa de Registro de Alumnos .............................................................................................. 16

description

Archivos y BD en C Sharp

Transcript of Archivos y BD en C Sharp

Page 1: Archivos y BD en C Sharp

Material preparado por Rodrigo Sandoval U en Mayo 2004

PONTIFICIA UNIVERSIDAD CATÓLICA DE CHILE ESCUELA DE INGENIERÍA DEPARTAMENTO DE CIENCIA DE LA COMPUTACIÓN IIC 1102 INTRODUCCIÓN A LA PROGRAMACIÓN Profesor: Rodrigo Sandoval U.

Capítulo IX – Archivos en C# y Bases de Datos

1 LECTURA Y ESCRITURA DE ARCHIVOS DE TEXTO.....................................................................................1 1.1 STREAMS ...............................................................................................................................................................1

1.1.1 Lectura de Archivos ......................................................................................................................................1 1.2 USING SYSTEM.IO .................................................................................................................................................2 1.3 CONTROL DE ERRORES ..........................................................................................................................................2 1.4 LECTURA: STREAMREADER...................................................................................................................................2

1.4.1 Constructores de StreamReader....................................................................................................................2 1.4.2 Lectura con StreamReader............................................................................................................................3 1.4.3 Ejemplo: Lectura de un Archivo de Texto, mostrando contenido en pantalla ..............................................3 1.4.4 Ejemplo: Procesamiento de Operaciones Matemáticas en Archivo .............................................................4

1.5 ESCRITURA: STREAMWRITER ................................................................................................................................6 1.5.1 Constructores de StreamWriter.....................................................................................................................6 1.5.2 Escritura con StreamWriter ..........................................................................................................................6 1.5.3 Ejemplo: Lectura y Escritura de un Archivo.................................................................................................7

2 BASES DE DATOS...................................................................................................................................................10 2.1 CONCEPTOS BÁSICOS DE BASES DE DATOS .........................................................................................................10

2.1.1 Base de Datos..............................................................................................................................................10 2.1.2 Sistema de Administración de Base de Datos .............................................................................................10 2.1.3 Elementos relacionados a una Base de Datos.............................................................................................10 2.1.4 EJEMPLO .....................................................................................................................................................0

2.2 MODELOS DE BASES DE DATOS ...........................................................................................................................12 2.2.1 Esquema de Archivos ..................................................................................................................................12 2.2.2 Modelo Jerárquico ......................................................................................................................................12 2.2.3 Modelo Relacional ......................................................................................................................................13 2.2.4 Modelo Distribuido .....................................................................................................................................15 2.2.5 Modelo de BD Orientado a Objeto .............................................................................................................15 2.2.6 BD Multidimensional ..................................................................................................................................15

2.3 PROGRAMACIÓN DE BASES DE DATOS CON C# ....................................................................................................16 2.3.1 Ejemplo: Programa de Registro de Alumnos ..............................................................................................16

Page 2: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 1

1 Lectura y Escritura de Archivos de Texto En todos los programas, la manera de almacenar y recuperar información que perdure en el tiempo se basa en el uso de “memoria secundaria”, compuesta esencialmente por discos (diskettes, discos duros, CD, DVD, etc.) y ocasionalmente cintas. En cualquiera de estos medios, la unidad de almacenamiento de información se denomina archivo.

Al igual que prácticamente todos los lenguajes de programación, C# ofrece el acceso a leer y escribir archivos en disco, por medio de estructuras especialmente definidas. En el caso de este lenguaje Orientado a Objeto, las estructuras consisten en clases de características y métodos particulares, que resuelven la problemática general de acceso a los archivos, permitiendo desarrollar programas que los utilicen como fuente de información y medio de almacenamiento de información de largo plazo.

1.1 Streams Un stream es como se denomina a un objeto utilizado para transferir datos. Estos datos pueden ser transferidos en dos posibles direcciones:

- Si los datos son transferidos desde una fuente externa al programa, entonces se habla de “leer desde el stream”.

- Si los datos son transferidos desde el programa a alguna fuente externa, entonces se habla de “escribir al stream”.

Frecuentemente, la fuente externa será un archivo, pero eso no necesariamente es el caso, por lo que el concepto es utilizado ampliamente con fuentes de información externas de diversos tipos. Algunas otras posibilidades fuera de los archivos incluyen:

- Leer o escribir datos a una red utilizando algún protocolo de red, donde la intención es que estos datos sean recibidos o enviados por otro computador.

- Lectura o escritura a un área de memoria.

- La Consola

- La Impresora

- Otros ...

Algunas clases que C# provee para resolver este acceso a fuentes diversas incluyen las clases de tipo Reader y Writer.

1.1.1 Lectura de Archivos Las clases más relacionadas con la escritura y lectura de archivos (File Input/Output o File I/O) son:

- FileStream, cuyo propósito es lectura y escritura de datos binarios (no de texto legible), a cualquier archivo de tipo binario, aunque se puede utilizar para acceder a cualquier tipo de archivo, inclusive los de texto.

- StreamReader y StreamWriter, las cuales están diseñadas para lectura y escritura de archivos de texto. Estas clases se asumen como de un nivel más alto que FileStream.

Una observación acerca de la declaración de nombres/rutas de archivos en C#. Usualmente, la ruta de un archivo contiene el carácter ‘\’, que en C# se utiliza como caracter de control para símbolos especiales (como el cambio de línea: ‘\n’). Sin embargo, entendiendo que no es el mismo sentido el que se le quiere dar en la interpretación de rutas de archivos (por ej: “C:\Mis documentos\Programas\ejemplo.cs”), se utiliza una sintaxis particular, anteponiendo el símbolo ‘@’ antes del string con la ruta del archivo. Es decir:

string rutaarchivo = @”C:\Temp\archivo.txt”;

Page 3: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 2

Esta declaración evita la interpretación de los dos caracteres ‘\’ como símbolos especiales y el string queda correctamente inicializado.

1.2 Using System.IO Para el uso de estas clases, es necesario referenciar el uso del namespace System.IO, ya que System no contiene los elementos para el manejo de archivos. Por ello, los programas con acceso a archivos deben incluir la línea:

using System.IO;

1.3 Control de Errores Si bien en una serie de instrucciones de ejecución en lenguaje C# se pueden producir errores importantes, particularmente cuando hay input del usuario que debería tener cierta forma o valores, o en cálculos matemáticos (específicamente evitando divisiones por cero), es factible en C# tener cierto control sobre el comportamiento del programa ante dichas situaciones.

Esencialmente, el bloque try-catch persigue precisamente tener cierto control sobre lo que el programa hará en caso de producirse un error.

public int division(int n1, int n2) { int resultado = 0; try { resultado = n1/n2; } catch(Exception e) { Console.WriteLine("Error en la división de {0}/{1}\n\n{2}",n1, n2,

e.ToString()); } }

1.4 Lectura: StreamReader La ventaja de esta clase es que hace una operación sobre archivos que resulta muy natural al momento de utilizarla.

1.4.1 Constructores de StreamReader El más simple de los constructores toma sólo el nombre/ruta del archivo a abrir para lectura:

StreamReader sr = new StreamReader(@”C:\Temp\archivo.txt”);

Sin embargo, reconociendo que hoy existen diferentes formatos (codificaciones) de archivos de texto y no solamente el tradicional formato ASCII, es factible establecer cuál es la codificación especial que este archivo de texto plano puede tener. Los formatos posibles son: ASCII, Unicode, UTF7, UTF8, BigEndianUnicode.

El constructor ad-hoc es:

StreamReader sr = new StreamReader(@”C:\Temp\file.txt”, Encoding.UTF8Encoding);

En términos prácticos, nos será necesario recurrir a este tipo de codificaciones, ya que usualmente se trabajará con codificación ASCII.

El constructor deja abierto el stream para poder recuperar la información del archivo desde la instancia de StreamReader declarada. Para cerrar un stream o archivo, se invoca el método Close():

sr.Close();

Page 4: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 3

1.4.2 Lectura con StreamReader Son básicamente tres los métodos propios de StreamReader que permiten efectuar lectura desde el stream (archivo) declarado.

1.4.2.1 ReadLine()

Al igual que el conocido Console.ReadLine(), este método lee una línea completa de un archivo de texto hasta el cambio de línea más próximo. Al igual que su equivalente de consola, StreamReader.ReadLine() no incluye en el string el carácter de cambio de línea.

string linea = sr.ReadLine()

1.4.2.2 ReadToEnd()

Este método, por su parte, se encarga de acumular la información que hay desde la lectura anterior (que pudo haberse hecho con ReadLine(), por ejemplo) hasta el final del archivo, todo en el mismo string.

string linea = sr.ReadToEnd()

1.4.2.3 Read ()

Finalmente, el método simple Read() se encarga de leer un caracter a la vez, lo que permite procesar símbolo por símbolo el contenido del archivo. Convenientemente, este método reconoce el cambio de línea y se lo salta como si no existiese. Cuando se encuentra con el fin de archivo, retorna un valor –1, considerando que su retorno es siempre un int (y no un char).

int SigCaracter = sr.Read();

Este mismo método ofrece una declaración alternativa (sobrecarga), donde es posible leer una cantidad específica de caracteres y almacenarlos en un arreglo de enteros.

char[] CharArray = new char[100];

int[] nChars = sr.Read(CharArray, 0, 100);

nChars es un arreglo con los enteros retornados por el método, y será menor si es que la cantidad de caracteres que quedan en el archivo es menor de 100.

1.4.3 Ejemplo: Lectura de un Archivo de Texto, mostrando contenido en pantalla ///////////////////////////////////////////////////////////////////////////////// // Ejemplo de Lectura de Archivos ///////////////////////////////////////////////////////////////////////////////// using System; using System.IO; class Archivo { StreamReader sr; bool abierto = false; // Constructor: Recibe el nombre del archivo y lo abre (con control errores) public Archivo(string filename) { try { sr = new StreamReader(filename); abierto = true; } catch(Exception e) { Console.WriteLine("Error en la apertura de \"{0}\": {1}",

filename, e.ToString()); }

Page 5: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 4

} public void Mostrar() { string linea; if(!abierto) return; // Si no se pudo abrir, no hay nada que leer linea = sr.ReadLine(); while(linea != null) { // Lee líneas mientras haya (mientras sean !=null) Console.WriteLine(linea); linea = sr.ReadLine(); } sr.Close(); abierto = false; } } class MainApp { static void Main() { string nombre; Console.Write("Nombre del archivo: "); nombre = Console.ReadLine(); Archivo archivo = new Archivo(nombre); archivo.Mostrar(); Console.ReadLine(); } }

1.4.4 Ejemplo: Procesamiento de Operaciones Matemáticas en Archivo ///////////////////////////////////////////////////////////////////////////////// // Ejemplo de Lectura de Archivos: Calculadora de Archivo // ====================================================== // Este ejemplo muestra cómo se procesa el contenido de un archivo, que indica // operaciones matemáticas básicas: * / + - ///////////////////////////////////////////////////////////////////////////////// using System; using System.IO; class Calculadora { StreamReader sr; bool abierto = false; // Constructor: Recibe el nombre del archivo y lo intenta abrir. // Si no puede abrirse para lectura, "abierto" queda como false public Calculadora(string filename) { try { sr = new StreamReader(filename); abierto = true; } catch(Exception e) { Console.WriteLine("Error en la apertura de \"{0}\": {1}",

filename,e.ToString()); } }

Page 6: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 5

// Operacion: Recibe la operación y dos números en forma de string. // Retorna el resultado (int) de la operación entre ambos números. int Operacion(string op, string n1, string n2) { switch(op) { case "+": return( int.Parse(n1) + int.Parse(n2)); case "-": return( int.Parse(n1) - int.Parse(n2)); case "*": return( int.Parse(n1) * int.Parse(n2)); case "/": return( int.Parse(n1) / int.Parse(n2)); } return(0); } // Procesar: lee líneas del archivo abierto, procesando el contenido en forma de operaciones. // Observaciones: al finalizar se cierra el stream. No se valida el formato de c/línea. public void Procesar() { string linea; string[] elementos; if(!abierto) return; // Si no se pudo abrir, no hay nada que leer linea = sr.ReadLine(); while(linea != null) { // Para poder usar Split(), las operaciones y los operandos deben // venir separados por espacios. elementos = linea.Split(); Console.WriteLine("{0} = {1}", linea,

Operacion(elementos[1], elementos[0], elementos[2])); linea = sr.ReadLine(); } sr.Close(); abierto = false; } } class MainApp { static void Main() { string nombre; Console.Write("Nombre del archivo: "); nombre = Console.ReadLine(); Calculadora c = new Calculadora(nombre); c.Procesar(); Console.ReadLine(); } }

Ejemplo de Ejecución:

Tomando el siguiente archivo de operaciones “calculos.txt”: 4 + 4 5 * 6 8 - 2 6 / 3

Resulta el siguiente output: Nombre del archivo: calculos.txt 4 + 4 = 8 5 * 6 = 30 8 - 2 = 6 6 / 3 = 2

Page 7: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 6

1.5 Escritura: StreamWriter Esta clase funciona prácticamente de la misma manera que StreamReader, excepto que su propósito es únicamente para escribir dentro de un archivo (u otro stream). Es relevante distinguir que en este caso, el proceso de apertura para escritura considera que:

- Si el archivo no existe lo crea vacío para comenzar a escribir.

- Si el archivo ya existe, lo deja vacío para comenzar a escribir.

- Si el archivo ya existe, es posible abrirlo en forma “Append” (agregar) para escribir al final.

1.5.1 Constructores de StreamWriter El más simple de los constructores toma sólo el nombre/ruta del archivo a abrir para escritura.

StreamWriter sw = new StreamWriter (@”C:\Temp\archivo.txt”);

Este constructor asume por defecto el formato UTF8 de archivos planos, ya que es el manejado por .NET. Sin embargo, existe el constructor equivalente que permite abrir un archivo especificando otra codificación de archivo plano, por ejemplo ASCII.

StreamWriter sw = new StreamWriter (@”C:\doc\file.txt”, Encoding.ASCII);

Un tercer constructor utiliza como segundo parámetro un boolean que indica si el archivo debe ser abierto para “Agregar”, es decir, en un modo Append.

StreamWriter sw = new StreamWriter (@”C:\Temp\archivo.txt”, true);

De la misma manera que en el caso de la lectura, para cerrar un stream o archivo, se invoca el método Close:

sw.Close();

1.5.2 Escritura con StreamWriter Son básicamente dos los métodos propios de StreamWriter que permiten escribir hacia el stream (archivo) declarado y son los mismos que se usan para escribir en la consola: Write() y WriteLine().

1.5.2.1 WriteLine()

Totalmente equivalente a Console.WriteLine(), se utiliza la misma idea, y el mismo formato, sabiendo que se estará escribiendo el texto no a la consola, sino que al stream abierto con el constructor.

string linea = “Texto de prueba”;

sw.WriteLine(linea);

sw.WriteLine(“Los valores posibles son: {0} y {1}”, 3, 5);

1.5.2.2 Write ()

También presente, el método simple Write(), permite escribir texto en el stream, de la misma forma que su equivalente método de la clase Console. En este caso se reconocen las siguientes alternativas de uso:

Imprimir un string string linea = “Texto de prueba”;

sw.Write(linea);

Page 8: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 7

Imprimir un caracter char caracter = ‘T’;

sw.Write(caracter);

Imprimir un arreglo de caracteres char[] caracteres = new char[100];

for(int i=0; i<100; i++) caracteres[i] = ‘+‘;

sw.Write(caracteres);

Imprimir una porción de un arreglo de caracteres char[] caracteres = new char[100];

for(int i=0; i<100; i++) caracteres[i] = ‘+‘;

sw.Write(caracteres, 25, 50); // Desde posición 25 se escriben 50 caracteres

1.5.3 Ejemplo: Lectura y Escritura de un Archivo ///////////////////////////////////////////////////////////////////////////////// // Ejemplo de Lectura de Archivos: Calculadora de Archivo // ====================================================== // Este ejemplo muestra cómo se procesa el contenido de un archivo, que indica // operaciones matemáticas básicas: * / + - // Este ejemplo en particular, escribe el resultado en un archivo destino ///////////////////////////////////////////////////////////////////////////////// using System; using System.IO; class Calculadora { StreamReader sr; StreamWriter sw; bool abierto1 = false; bool abierto2 = false; // Constructor: Recibe el nombre del archivo y lo intenta abrir. // Si no puede abrirse para lectura, "abierto" queda como false // Si lo puede abrir, crea un segundo archivo con un nombre similar. public Calculadora(string filename) { try { sr = new StreamReader(filename); abierto1 = true; } catch(Exception e) { Console.WriteLine("Error en la apertura de \"{0}\": {1}",

filename,e.ToString()); } if(abierto1) { string nombrearchivo2; // Transforma "nombre.txt" en "nombre.out.txt" nombrearchivo2 = filename.Insert(filename.IndexOf('.'),".out"); try { sw = new StreamWriter(nombrearchivo2); abierto2 = true; } catch(Exception e) { Console.WriteLine("Error en la apertura de \"{0}\": {1}",

Page 9: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 8

nombrearchivo2,e.ToString()); } } } // Operacion: Recibe la operación y dos números en forma de string. // Retorna el resultado (int) de la operación entre ambos números. int Operacion(string op, string n1, string n2) { switch(op) { case "+": return( int.Parse(n1) + int.Parse(n2)); case "-": return( int.Parse(n1) - int.Parse(n2)); case "*": return( int.Parse(n1) * int.Parse(n2)); case "/": return( int.Parse(n1) / int.Parse(n2)); } return(0); } // Procesar: lee el archivo abierto, línea por línea,

// procesando el contenido en forma de operaciones y escribiendo // el resultado en un segundo archivo.

// Observaciones: Al finalizar se cierran los dos streams. // No se valida el formato de c/línea.

public void Procesar() { string linea, linea2; string[] elementos; // Si no se pudo abrir, no se podrá leer ni escribir if(!abierto1 || !abierto2) return; Console.WriteLine("Procesando ..."); linea = sr.ReadLine(); while(linea != null) { elementos = linea.Split(); // ahora graba los resultados en el segundo archivo linea2 = linea + " = " +

Operacion(elementos[1], elementos[0], elementos[2]).ToString(); sw.WriteLine(linea2); linea = sr.ReadLine(); } sr.Close(); abierto1 = false; sw.Close(); abierto2 = false; Console.WriteLine("Listo"); } } class MainApp { static void Main() { string nombre; Console.Write("Nombre del archivo: "); nombre = Console.ReadLine(); Calculadora c = new Calculadora(nombre); c.Procesar(); Console.ReadLine(); } }

Al abrir el archivo calculos.txt, se crea el archivo calculos.out.txt con el siguiente contenido:

Page 10: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 9

4 + 4 = 8 5 * 6 = 30 8 - 2 = 6 6 / 3 = 2

Page 11: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 10

2 Bases de Datos Uno de los grandes objetivos de la computación es la capacidad de procesar datos: muchos datos, en forma rápida, eficiente, y segura (confiable). Esto no era posible con métodos manuales tradicionales. Hoy en día existen muchas aplicaciones computacionales, pero para este contexto se vuelven muy importantes aquellas que trabajan directamente con la administración de datos.

2.1 Conceptos Básicos de Bases de Datos Para la realidad computacional de nuestros días, es necesario definir dos elementos puntuales que existen en todo gran o pequeño sistema que maneje cantidades de datos: la Base de Datos (BD) y el Sistema Administrador de Base de Datos (DBMS).

2.1.1 Base de Datos Se puede definir como “Una colección estructurada y organizada de datos y de otros objetos que permiten trabajar con esos datos”. Si se habla de “bolsón de datos”, no se incluye un concepto de “orden” o “estructuración”. Una base de datos tiene una estructura claramente definida, sin importar el nivel de complejidad de esta estructura. Tradicionalmente, los datos se manejan en estructuras uniformes, que se pueden comparar con planillas de datos. Es decir, una base de datos contiene varias planillas de datos diversos, que pueden a su vez estar relacionados o no.

2.1.2 Sistema de Administración de Base de Datos Se puede definir como “Un elemento capaz de manejar los datos contenidos en una Base de Datos a través de operaciones claramente establecidas”. Si la Base de Datos contiene los objetos que corresponden a los datos y otras estructuras adicionales, el DBMS (Data Base Manager System) se encarga de accesar esos datos, utilizando operaciones básicas como: agregar, eliminar, modificar, buscar.

Un DBMS es un grupo de programas que se encargan de administrar estas operaciones y todos los elementos que facilitan su ejecución.

2.1.3 Elementos relacionados a una Base de Datos Al trabajar con los datos de una BD, se deben mantener elementos que apoyan el acceso adecuado a las estructuras de datos. Se distinguen:

• Planillas de datos: tablas que contienen filas, cada una representa un objeto de un tipo común para las filas de la tabla, que a su vez se compone de varios “atributos” o propiedades que se ordenan en las columnas de la planilla.

• Registro: una fila de una tabla. Representa un objeto de un tipo definido y se compone de atributos.

• Campos: son precisamente la definición de estos “atributos” de la tabla o planilla.

• Llave Primaria: es una parte de los campos de un registro que permite distinguirlo en forma única del resto de registros adicionales.

• Indices: al igual que el índice de un libro, un índice de una BD, que se asocia a una sola tabla, referencia la posición de un registro dentro de una tabla, de acuerdo a un orden predefinido.

• Vistas: son “ángulos” de la BD. Al igual que una persona puede ver un auto desde el exterior, lo cual constituye la vista “externa” del vehículo, existe otra vista interior, y por su parte el objeto “vehículo” posee muchas propiedades o atributos que no son visibles en algunas vistas.

Page 12: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 0

2.1.4 EJEMPLO En una Compra-Venta de autos usados se manejan los datos de los vehículos existentes en el momento. Para poder utilizar información adecuada, se entiende que un auto es un objeto de tipo vehículo, y como tal posee ciertas características determinables: Marca y Modelo, Patente, Número de Puertas, Cilindraje, Color. Aplicando los conceptos mencionados de Bases de Datos:

Planilla de Datos o Tabla

Marca y Modelo Patente Nº Puertas Cilindraje Color

Suzuki Samurai HK-2367 3 1200 Azul

Subaru Impreza JG-2304 4 1800 Blanco

Chevrolet Cavalier LM-3948 4 1600 Rojo

Toyota Corolla TF-3404 4 1800 Gris

Toyota Corolla HK-2376 4 1600 Verde

Chevrolet Cavalier BC-2340 4 1600 Rojo

Llave Primaria

La llave primaria se obtiene al seleccionar una combinación de campos cuyos valores combinados no se repitan para más de un registro. En este caso, podemos ver que el Nº de puertas es repetido, al igual que el color y el cilindraje. La marca y el modelo también se repiten, pero claramente ningún auto posee la misma patente de otro. Entonces la “Patente” es la candidata ideal para ser una llave Primaria.

Indice

Puede ser relevante ordenar la lista de autos por orden alfabético de la Marca+Modelo. Es decir, el índice sería el que se ve a continuación:

Chevrolet Cavalier BC-2340

Chevrolet Cavalier LM-3948

Subaru Impreza JG-2304

Suzuki Samurai HK-2367

Toyota Corolla HK-2376

Toyota Corolla TF-3404

Campos

Registro

Page 13: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 12

Vista

Como “visión parcial” de los datos se puede definir verbalmente algo como “Todos aquellos autos, identificados por modelo, patente, y cilindraje, cuyo cilindraje sea mayor o igual a 1.700.

Marca y Modelo Patente Cilindraje

Subaru Impreza JG-2304 1800

Toyota Corolla TF-3404 1600

2.2 Modelos de Bases de Datos Dados los conceptos básicos de una BD, a través del tiempo, ya para diversas necesidades se han diseñado algunos esquemas o modelos que difieren en su estructura, lo cual muchas veces trae ventajas y desventajas. Muchos de los modelos diseñados han quedado obsoletos frente a otros que cumplen de mejor manera con las exigencias funcionales. Algunas de las características que deben tener:

• Consistencia en los datos (todos los datos dicen lo mismo, no hay contradicciones)

• Orden (permite saber qué existe y qué no existe, y dónde)

• Rapidez en la búsqueda (necesidad de la realidad informática de hoy)

• Integridad de los datos (que su solidez se garantice evitando perder datos valiosos con operaciones indirectas).

• Acceso compartido a los datos (de modo que distintas “entidades” (usuarios, aplicaciones, etc.) puedan acceder simultáneamente a los datos.

2.2.1 Esquema de Archivos Originalmente, los datos eran almacenados en archivos “planos”, que no contenían más que una única estructura básica de “tabla”, donde cada registro ocupa un largo fijo de bytes y sus campos son estáticos. Se habla de “Archivos Secuenciales”, ya que los registros son almacenados en orden de llegada y se mantienen en ese orden (muy rígido). Para apoyar las exigencias a este esquema, se utilizan archivos adicionales para manejar los índices (utilizando el término “archivos indexados”), aunque las operaciones básicas de inserción y eliminación funcionan bastante bien.

La indexación (aplicación de índices) se realizaba de diversas maneras: índices absolutos, relativos. Esquemas posteriores permitieron cambiar el esquema secuencial a un de tipo “Árbol”, donde la manera de guardar los datos obedece a un esquema estructurado y jerárquico, de acuerdo a un orden preestablecido.

Tradicionalmente se utilizaron productos comerciales, tanto lenguajes de programación, como DBMS (por así nombrarlos) que manejan este esquema: lenguaje COBOL, archivos DBF (dBase, Clipper).

En este capítulo es un esquema de este tipo el que se aprovecha al manejar archivos con C#, en un ejemplo más adelante.

2.2.2 Modelo Jerárquico Este modelo más complejo, a través de la identificación de relaciones entre los tipos de objetos que se quieren almacenar, es capaz de construir una especia de red o más bien, árbol de datos, donde existen precedencias en cuanto a la estructura de orden. Esto se puede ver en el siguiente ejemplo.

Page 14: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 13

Nº Curso Título Descripción

CURSO

REQUISITO

Nº Curso Título

DICTAR

Día Hora Sala

NombreNº Profesor

PROFESOR ALUMNO

Nº Alumno Nombre Nota

Este modelo muestra una realidad de una universidad, donde se dictan cursos de distinto tipo que tienen prerrequisitos, profesor (o profesores) que dicta(n) el curso, y alumnos que lo toman. Se distinguen algunos elementos como “Nº Alumno” como identificador de alumno. Un ejemplo puntual de este modelo podría darse con los siguientes datos:

AN-21 Computación II Computación orientada a....

AN-11 Computación I

Miércoles 19:00 N7

23 Pérez1023 Alvarez 5,8

1293 Barrios 5,4

987 Cabrera 6,2

El primer sistema que existió con esta esquema fue el IMS (Information Managment System) desarrollado en 1960. Este fue el precursor que fue aprovechado en la NASA en la década de los ’60, en particular en el proyecto Apollo. Luego apareció System 2000 desarrollado por Intel.

Una de las grandes ventajas de este sistema fue la posibilidad de estructurar datos en una forma más completa que el esquema de archivos simples. Aún así, se vió en aprietos al momento de representar situaciones donde la naturaleza de los datos implicaba una doble jerarquía, o al momento de consultar sobre datos particulares.

2.2.3 Modelo Relacional Fruto del trabajo de E.F. Codd, y sus publicaciones de la década de los ’70, nació el System R que implementaba un modelo bautizado como Relacional. La gran característica de este modelo es que las tablas que manejaba representaban entidades, que en la realidad tenían ciertos vínculos entre ellas. Estos vínculos son conocidos como relaciones.

2.2.3.1 Tipos de Relaciones

Al identificar dos o más entidades que están vinculadas, se distingue una relación. Esta puede tener distinta “cardinalidad”, lo que se refiere a las “repeticiones” que se encuentran del vínculo. Supongamos las entidades del ejemplo de cursos en una universidad: curso, profesor, alumno. Cada curso puede ser dictado por uno o más profesores, asisten varios alumnos a ese curso, los cuáles, a su vez asisten a otros cursos.

Page 15: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 14

2.2.3.2 Relación 1 a 1

Cuando dos entidades se relacionan en forma “única”. Por ejemplo, si se diera como restricción que cada curso es dictado por un solo profesor, entonces Profesor es 1 a 1 a Curso.

2.2.3.3 Relación 1 a N

Cuando dos entidades se relacionan de modo que una se relaciona varias veces con la otra. Por ejemplo, cada curso debe dictarse en una única sala (1), pero en una sala se dictan varios cursos (a distintas horas obviamente), entonces Curso es 1 a N a Sala.

2.2.3.4 Relación N a N

Cuando dos entidades se relacionan en forma “abierta”, es decir muchos de un tipo se relacionan con muchos del otro. Por ejemplo, los alumnos toman varios cursos y a su vez cada curso integra a varios alumnos, entonces Alumno es N a N a Curso.

Este modelo de BD se desarrolló fuertemente en los ’80 y sigue siendo hasta hoy muy utilizado en forma comercial y universal.

Otro de los grandes aportes desde el punto de vista de la ciencia que se hizo con este modelo es el álgebra relacional, donde en una manera formal se pueden establecer las relaciones entre las distintas entidades y cuáles son las características de estas relaciones.

2.2.3.5 Formas Normales

Para asegurar consistencia de los datos, integridad, y evitar redundancia y otras anomalías que algunos esquemas de datos proveen, en el modelo relacional es posible diseñar un esquema de tablas y relaciones que para un caso puntual pueda asegurar de mejor manera esa integridad y consistencia.

Esta definición se hace a través de Formas Normales, las cuáles definen ciertas reglas que deben cumplir los registros de cada tabla para asegurar estas características.

Existen las formas Normales: 1NF, 2NF, 3NF y BCNF. Cada una de estas establece ciertas características que permiten mejorar la consistencia de datos, y la integridad.

Por ejemplo, en el ejemplo de los Cursos de la Universidad, es posible definir un esquema de datos que maneje todos los datos de una manera muy rudimentaria. De esa manera se tendría una tabla como la siguiente:

Nº Curso Título Descripción Nombre Prof. Sala Día Hora Alumno Nota

AN-21 C. II Compu.... Pérez N7 Mie 19:00 Alvarez 5,6

AN-21 C. II Compu.... Pérez N7 Mie 19:00 Barrios 5,8

AN-21 C. II Compu.... Pérez N7 Mie 19:00 Cabrera 6,2

Después de aplicar ciertas reglas los datos podrían guardarse en varias tablas. En el esquema rudimentario recién mostrado, se pueden producir los siguientes problemas:

- Redundancia: el curso, su profesor y la sala se repiten para cada alumno del curso.

Page 16: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 15

- Inconsistencia: es posible que en el primer registro diga AN-21 con Pérez como profesor, pero en el 2º. Registro puede decir AN-21, con Sánchez como profesor. No hay cómo saber cuál es el correcto.

- Problemas de inserción. Si agrego un nuevo alumno debo repetir todos los datos.

- Problemas de eliminación. Si elimino todos los registros de los alumnos (es decir, este curso no tuvo alumnos), entonces se pierde la información del profesor que había sido designado.

En el esquema relacional adecuado, aplicando algún nivel de formas normales se pueden evitar todos estos problemas definiendo tablas separadas, usualmente distinguiendo entidades distintas, y relaciones más complejas (N a N).

2.2.4 Modelo Distribuido A veces aplicable a varias de las estructuras existentes, la idea del modelo distribuido es repartir los datos en distintas tablas que están ubicadas en distintas posiciones en una red de computadores. Este esquema se hace necesario cuando la administración compartida y global de la información consume demasiados recursos: canal de comunicación de red, espacio en discos de los computadores, etc. Lo que se busca con este esquema es repartir los datos de manera que el tráfico de datos por la red se vea disminuido, a la vez que se permite que cada unidad que solicita datos a esta BD distribuida, pueda obtenerlos adecuadamente.

2.2.5 Modelo de BD Orientado a Objeto Buscando mejorar el rendimiento de un DBMS ante eventuales búsquedas complejas de información de la BD, se diseño la BD OO (Orientada a Objetos). En ella, cada entidad se distingue como un obejto que tiene Propiedades, Atributos (Campos) y Operaciones definidas que accesan esta información.

2.2.6 BD Multidimensional Con el creciente desarrollo de las aplicaciones computacionales orientadas a dar información de alto nivel, es decir, información que ha pasado por varias etapas de proceso desde el detalle de los datos, se han desarrollados esquemas que son capaces de contestar complejas preguntas que requieren de valores a un alto nivel de agregación de los datos originales. Cuando se habla de la gestión de una empresa, hoy en día se habla de obtener información desde los datos originales que permitan tomar decisiones de acuerdo al comportamiento del negocio reflejado por los datos analizados en diversas dimensiones.

En palabras más simples, cuando se requieren analizar los datos de ventas de productos de una fábrica, tanto por línea de producto, o distribución geográfica, o través del tiempo, es necesario tener parte de los datos “ya digeridos”. Si se intenta hacer sumas de detalles de facturas emitidas para obtener la información, según un esquema relacional, la respuesta demorará largo tiempo en llegar, dependiendo de la cantidad de datos existentes.

Una BD multidimensional utiliza un esquema en que los datos han sido procesados (sumados, recalculados totales, etc.) hasta cierto nivel y se organizan de acuerdo a las dimensiones relevantes del negocio. Esto permite contestare con buena eficiencia complejas preguntas, como tendencias, etc., pero imposibilita poder analizar una factura en particular (datos a gran nivel de detalle).

Page 17: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 16

2.3 Programación de Bases de Datos con C# Si bien hoy existen numerosas tecnológicas maduramente desarrolladas para administrar datos en Bases de Datos, incluyendo lenguajes de manejo especializados, como es el SQL, es factible hacer programas que incluyan el manejo simple de información en archivos de datos de formato definido y acotado.

En la gran mayoría de estos programas, se define lo que se conoce como una capa lógica, que se conforma de clases que representan los datos almacenados en las diferentes tablas (o archivos), de modo que el resto del programa sólo conoce la forma lógica de estas clases, y desconoce el formato de las tablas o archivos.

2.3.1 Ejemplo: Programa de Registro de Alumnos

Definición del Problema

En este ejemplo, se considera un almacenamiento de datos en archivos para poder hacer el registro de alumnos en cursos para semestres específicos. Pensando en un modelo estilo Relacional, se determinan las siguientes entidades de información relevantes:

- El alumno, detallado con nombre, apellido, Nº alumno (único), fecha nacimiento (forma ddmmaaaa), y edad.

- El curso dictado, identificado por su sigla (única), su descripción, y la cantidad de créditos.

- La inscripción, que relaciona un alumno (identificado por su Nº) con un curso (identificado por su sigla), asociado a un semestre en particular (de la forma aaaan, donde aaaa es el año y n el semestre).

En este caso particular, se requiere permitir las siguientes operaciones:

- Ingresar un nuevo alumno

- Ingresar un nuevo curso

- Inscribir un alumno en un curso, en un semestre particular

- Mostrar todos los cursos

- Mostrar todos los alumnos

- Mostrar todas las inscripciones realizadas

- Leer los datos de los archivos correspondientes

- Guardar los datos de los archivos correspondientes.

Elementos Involucrados: la lista de alumnos, la lista de cursos, y la lista de inscripciones.

Conceptualización de la Solución

Para este programa se requiere implementar las entidades: Lista de Alumnos, Lista de Cursos, Inscripciones.

Las clases necesarias para implementar estas entidades son las siguientes:

- Alumno y ListaAlumnos

- Curso y ListaCursos

- Inscripción y ListaInscripciones

Clase Alumno: contiene los datos básicos de cada alumno y propiedades que permiten acceder a ellos

Clase ListaAlumnos: maneja un conjunto de alumnos, permitiendo cargar y guardar datos de y hacia un archivo de texto con un formato específico y adecuado. Adicionalmente permite operaciones como: Agregar Alumnos, Mostrar los Alumnos registrados, Buscar un Alumno en particular.

Page 18: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 17

Las clases Curso, ListaCurso, Inscripcion, y ListaInscripciones ofrecen elementos equivalentes, cada una en su propio contexto de información a manejar.

Adicionalmente, en la clase principal ofrece métodos para la manipulación general de los datos, como son:

- Menú de opciones

- Creación de un nuevo Alumno, preguntando sus datos

- Creación de un nuevo Curso, preguntando sus datos

- Registro de una nueva inscripción, preguntando y validando el curso y el alumno correspondiente.

Algoritmo Principal

1. Crear las instancias de las listas de datos Leer los archivos con datos

2. Repetir mientras la opción seleccionada no sea “Salir”

a. Mostrar Menú de Opciones

b. Preguntar opción

c. Si la opción no es “Salir”

i. Ejecutar Opción

3. Grabar datos en archivos desde las listas

Limitaciones

El programa no hace todas las validaciones de datos ingresados por el usuario, pero particularmente requiere lo siguiente:

- Las descripciones de cursos deben ser un único string sin espacios entre medio.

- Los nombres y apellidos no pueden ser compuestos (o al menos, no separados por espacios)

- Sólo se maneja un número limitado de alumnos, un número limitado de cursos, y un número limitado de inscripciones

- Si bien se valida la existencia de los archivos antes de leerlos, se muestra un mensaje en pantalla derivado del registro de error de la plataforma .NET.

Código Fuente de la Solución ///////////////////////////////////////////////////////////////////////////////// // Ejemplo de Manejo de Datos en Archivos - Inscripción de Alumnos en Cursos // ========================================================================= ///////////////////////////////////////////////////////////////////////////////// using System; using System.IO; // Namespace de clases StreamReader y StreamWriter, para archivos //------------------------------------------------------------------------ //------------------------------------------------------------------------ // Clase Curso: representa un curso con sus atributos básicos //------------------------------------------------------------------------ class Curso { string sigla, descripcion; int creditos;

Page 19: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 18

public Curso(string s, string d, int c) { sigla = s.ToUpper(); descripcion = d.ToUpper(); creditos = c; }

public string Sigla { get { return(sigla); } } public string Descripcion { get { return(descripcion); } } public int Creditos { get { return(creditos); } } } //------------------------------------------------------------------------ //------------------------------------------------------------------------ // Clase ListaCursos: representa un conjunto de cursos //------------------------------------------------------------------------ class ListaCursos { Curso[] cursos; // Almacena la lista de cursos int cantidad = 0; const int MAX = 20; // Limitación: 20 cursos máx string archivo = "cursos.dat"; // ------------------------------------------------------------------ // Constructor: dimensiona la lista de alumnos en MAX public ListaCursos() { cursos = new Curso[MAX]; } // Limitación: 20 cursos máx // ------------------------------------------------------------------ // Constructor: dimensiona la lista de cursos en MAX // y carga los datos de archivo identificado por su nombre public ListaCursos(string filename) { StreamReader fr; cursos = new Curso[MAX]; archivo = filename; try { fr = new StreamReader(archivo); } catch(Exception e) { //OJO: esta línea indicará warning: no se usa ‘e’ // No se pudo abrir: se crea StreamWriter sw = new StreamWriter(archivo); sw.Close(); return; } string linea; linea = fr.ReadLine(); while(linea != null) { string[] datos = linea.Split(); // Formato del archivo tiene: creditos sigla descripción Agregar(datos[1].ToUpper(), datos[2].ToUpper(), int.Parse(datos[0])); linea = fr.ReadLine(); } fr.Close(); } // ---------------------------------------------------------------------------- // Guardar(): guarda datos en estructura al archivo identificado por su nombre public bool Guardar() { StreamWriter fw; try { fw = new StreamWriter(archivo); } catch(Exception e) { Console.WriteLine("Error en la apertura de \"{0}\": {1}",

archivo,e.ToString()); return (false); } for(int i=0; i<cantidad; i++) fw.WriteLine("{0} {1} {2}",

Page 20: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 19

cursos[i].Creditos, cursos[i].Sigla, cursos[i].Descripcion); fw.Close(); return (true); } // ------------------------------------------------------------------ // Agregar(): agrega un curso dado a la lista // Parámetros: Curso c, el curso a agregar public void Agregar(Curso c) { if(cantidad<MAX) cursos[cantidad++] = c; } // ------------------------------------------------------------------ // Agregar(): agrega un curso dados sus datos, a la lista // Parámetros: la sigla, la descripción, y los créditos public void Agregar(string s, string d, int c) { if(cantidad<MAX) { cursos[cantidad++] = new Curso(s,d,c); } } // ------------------------------------------------------------------- // Atributo Cantidad - sólo lectura, no se puede modificar "por fuera" public int Cantidad { get { return(cantidad); } } // ------------------------------------------------------------------------------- // Mostrar(): muestra los datos registrados al momento public void Mostrar() { Console.WriteLine("\nCURSOS:"); for(int i=0; i<cantidad; i++) Console.WriteLine("{0} {1} {2}",

cursos[i].Creditos, cursos[i].Sigla, cursos[i].Descripcion); Console.WriteLine("----------------------------------------------------\n"); } // ------------------------------------------------------------------------------- // Buscar(): Busca curso definido por sigla. Retorna la posición, -1 si no está. public int Buscar(string sigla) { for(int i=0; i<cantidad; i++) if( cursos[i].Sigla == sigla.ToUpper() ) return(i); return(-1); // Si llegó aquí: no lo encontró } // ------------------------------------------------------------------------------ // GetCurso(): Entrega curso ubicado en la posición n del arreglo, con n de 0..N-1 public Curso GetCurso(int n) { return(cursos[n]); } } //------------------------------------------------------------------------ //------------------------------------------------------------------------ // Clase Alumno: representa un alumno con sus atributos básicos //------------------------------------------------------------------------ class Alumno { string nombre, apellido; string fechanac; int numero; public Alumno(int num, string n, string a, string f) {

numero = num; nombre = n.ToUpper(); apellido = a.ToUpper(); fechanac = f; }

public string Nombre { get { return(nombre); } } public string Apellido { get { return(apellido); } }

Page 21: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 20

public string FechaNac { get { return(fechanac); } } public int Numero { get { return(numero); } } } //------------------------------------------------------------------------ //------------------------------------------------------------------------ // Clase ListaAlumnos: representa un conjunto de alumnos //------------------------------------------------------------------------ class ListaAlumnos { Alumno[] alumnos; // Almacena la lista de alumnos int cantidad = 0; const int MAX = 20; // Limitación: 20 alumnos máx string archivo = "alumnos.dat"; // ------------------------------------------------------------------ // Constructor: dimensiona la lista de alumnos en MAX public ListaAlumnos(){ alumnos = new Alumno[MAX]; } // Limitación: 20 alumnos máx // ------------------------------------------------------------------ // Constructor: dimensiona la lista de alumnos en MAX // y carga los datos de archivo identificado por su nombre public ListaAlumnos(string filename) { StreamReader fr; alumnos = new Alumno[MAX]; archivo = filename; try { fr = new StreamReader(archivo); } catch(Exception e) { //OJO: esta línea indicará warning: no se usa ‘e’ // No se pudo abrir: se crea StreamWriter sw = new StreamWriter(archivo); sw.Close(); return; } string linea; linea = fr.ReadLine(); while(linea != null) { string[] datos = linea.Split(); // Formato del archivo tiene: num fecha nombre apellido Agregar(int.Parse(datos[0]), datos[2], datos[3], datos[1]); linea = fr.ReadLine(); } fr.Close(); } // -------------------------------------------------------------------------------- // Guardar(): guarda datos en la estructura al archivo identificado por su nombre public bool Guardar() { StreamWriter fw; try { fw = new StreamWriter(archivo); } catch(Exception e) { Console.WriteLine("Error en la apertura de \"{0}\": {1}",

archivo,e.ToString()); return (false); } for(int i=0; i<cantidad; i++) fw.WriteLine("{0} {1} {2} {3}",

alumnos[i].Numero, alumnos[i].FechaNac, alumnos[i].Nombre, alumnos[i].Apellido); fw.Close(); return (true);

Page 22: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 21

} // ------------------------------------------------------------------ // Agregar(): agrega un alumno dado a la lista // Parámetros: Alumno a, el alumno a agregar public void Agregar(Alumno a) { if(cantidad<MAX) alumnos[cantidad++] = a; } // ------------------------------------------------------------------ // Agregar(): agrega un alumno dados sus datos, a la lista // Parámetros: el número, nombre, apellido, y fecha nacimiento public void Agregar(int num, string n, string a, string f) { if(cantidad<MAX) { alumnos[cantidad++] = new Alumno(num,n,a,f); } } // ------------------------------------------------------------------- // Atributo Cantidad - sólo lectura, no se puede modificar "por fuera" public int Cantidad { get { return(cantidad); } } // ------------------------------------------------------------------------------- // Mostrar(): muestra los datos registrados al momento public void Mostrar() { Console.WriteLine("\nALUMNOS:"); for(int i=0; i<cantidad; i++) Console.WriteLine("{0} {1} {2} {3}",

alumnos[i].Numero, alumnos[i].FechaNac, alumnos[i].Nombre, alumnos[i].Apellido); Console.WriteLine("-----------------------------------------------------"); } // ------------------------------------------------------------------------ // Buscar(): Busca alumno definido por su numero. Retorna posición, -1 si no está. public int Buscar(int numero) { for(int i=0; i<cantidad; i++) if( alumnos[i].Numero == numero ) return(i); return(-1); // Si llegó aquí: no lo encontró } // ------------------------------------------------------------------------------- // GetAlumno(): Entrega alumno ubicado en posición n del arreglo, con n de 0..N-1 public Alumno GetAlumno(int n) { return(alumnos[n]); } } //------------------------------------------------------------------------ //------------------------------------------------------------------------ // Clase Inscripcion: representa la relación entre un alumno y un curso //------------------------------------------------------------------------ class Inscripcion { string sigla; int numero, semestre; public Inscripcion(string s, int n, int m) {

sigla = s.ToUpper(); numero = n; semestre = m; }

public string Sigla { get { return(sigla); } } public int Numero { get { return(numero); } } public int Semestre { get { return(semestre); } } }

Page 23: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 22

//------------------------------------------------------------------------ //------------------------------------------------------------------------ // Clase ListaInscripciones: representa un conjunto de inscripciones //------------------------------------------------------------------------ class ListaInscripciones { Inscripcion[] inscripciones; // Almacena la lista de inscripciones int cantidad = 0; const int MAX = 60; // Limitación: 60 inscripciones máx string archivo = "inscripciones.dat"; // ------------------------------------------------------------------ // Constructor: dimensiona la lista de inscripciones en MAX public ListaInscripciones() { inscripciones = new Inscripcion[MAX]; } // ------------------------------------------------------------------ // Constructor: dimensiona la lista de inscripciones en MAX // y carga los datos de archivo identificado por su nombre public ListaInscripciones(string filename) { StreamReader fr; inscripciones = new Inscripcion[MAX]; archivo = filename; try { fr = new StreamReader(archivo); } catch(Exception e) { //OJO: esta línea indicará warning: no se usa ‘e’ // No se pudo abrir: se crea StreamWriter sw = new StreamWriter(archivo); sw.Close(); return; } string linea; linea = fr.ReadLine(); while(linea != null) { string[] datos = linea.Split(); // Formato del archivo tiene: sigla numero semestre Agregar(datos[0].ToUpper(), int.Parse(datos[1]), int.Parse(datos[2])); linea = fr.ReadLine(); } fr.Close(); } // ------------------------------------------------------------------------------- // Guardar(): guarda datos en la estructura al archivo identificado por su nombre public bool Guardar() { StreamWriter fw; try { fw = new StreamWriter(archivo); } catch(Exception e) { Console.WriteLine("Error en la apertura de \"{0}\": {1}",

archivo,e.ToString()); return (false); } for(int i=0; i<cantidad; i++) fw.WriteLine("{0} {1} {2}", inscripciones[i].Sigla, inscripciones[i].Numero,

inscripciones[i].Semestre); fw.Close(); return (true); } // ------------------------------------------------------------------ // Agregar(): agrega una inscripción dada a la lista // Parámetros: Inscripcion i, el curso a agregar

Page 24: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 23

public void Agregar(Inscripcion i) { if(cantidad<MAX) inscripciones[cantidad++] = i; }

// ------------------------------------------------------------------ // Agregar(): agrega un curso dados sus datos, a la lista // Parámetros: la sigla, la descripción, y los créditos public void Agregar(string s, int n, int m) { if(cantidad<MAX) { inscripciones[cantidad++] = new Inscripcion(s,n,m); } } // ------------------------------------------------------------------- // Atributo Cantidad - sólo lectura, no se puede modificar "por fuera" public int Cantidad { get { return(cantidad); } } // ------------------------------------------------------------------------------ // Mostrar(): muestra los datos registrados al momento public void Mostrar(ListaAlumnos la, ListaCursos lc) { Console.WriteLine("\nINSCRIPCIONES:"); for(int i=0; i<cantidad; i++) { Alumno a; Curso c; a = la.GetAlumno(la.Buscar(inscripciones[i].Numero)); c = lc.GetCurso(lc.Buscar(inscripciones[i].Sigla)); Console.WriteLine("{0} ({1}) - {2} ({3} {4}) en {5}", c.Sigla, c.Descripcion, a.Numero, a.Nombre, a.Apellido,

inscripciones[i].Semestre); } Console.WriteLine("----------------------------------------------------\n"); } } //------------------------------------------------------------------------ //------------------------------------------------------------------------ // Clase MainApp: Bloque del Algoritmo Principal y métodos auxiliares //------------------------------------------------------------------------ class MainApp { // ---------------------------------------------------- // ValidarFecha(): valida una fecha en formato ddmmaaaa static bool ValidarFecha(string fecha) { string digitos = "0123456789"; if(fecha.Length!=8) return (false); for(int i=0; i<fecha.Length; i++)

if(digitos.IndexOf(fecha[i])<0) return (false); if(int.Parse(fecha.Substring(0,2))>31) return (false); if(int.Parse(fecha.Substring(0,2))==0) return (false); if(int.Parse(fecha.Substring(2,2))>12) return (false); if(int.Parse(fecha.Substring(2,2))==0) return (false); return (true); } static Alumno NuevoAlumno() { string nombre, apellido, fechanac; int numero; Console.WriteLine("Datos del nuevo alumno"); Console.Write("Nombre: "); nombre = Console.ReadLine(); Console.Write("Apellido: "); apellido = Console.ReadLine();

Page 25: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 24

do { Console.Write("Fecha Nac (ddmmaaaa): "); fechanac = Console.ReadLine(); } while (!ValidarFecha(fechanac)); Console.Write("Numero: "); numero = int.Parse(Console.ReadLine()); return(new Alumno(numero, nombre, apellido, fechanac)); } static Curso NuevoCurso() { string sigla, descripcion; int creditos; Console.WriteLine("Datos del nuevo curso"); Console.Write("Sigla: "); sigla = Console.ReadLine(); Console.Write("Descripción: "); descripcion = Console.ReadLine(); Console.Write("Créditos: "); creditos = int.Parse(Console.ReadLine()); return(new Curso(sigla, descripcion, creditos)); } // -------------------------------------------------------------------------- // NuevaInscripcion(): Crea una nueva inscripción relacionando un alumno existente // con un curso que también debe ser existente. // Observaciones: Se le pide al usuario sólo el Nº del alumno y la sigla del curso, // validando que ambos existan. static Inscripcion NuevaInscripcion(ListaAlumnos la, ListaCursos lc) { string sigla; int numero, semestre; Alumno a; Curso c;

// Muestra listas en pantalla para ayudar al usuario a indicar datos. la.Mostrar(); lc.Mostrar(); Console.WriteLine("Inscripción de Curso:"); do {

Console.Write("Nº Alumno: "); numero = int.Parse(Console.ReadLine()); } while( la.Buscar(numero)<0 );

do { Console.Write("Sigla Curso: "); sigla = Console.ReadLine(); } while( lc.Buscar(sigla)<0 );

Console.Write("Semestre: "); semestre = int.Parse(Console.ReadLine()); a = la.GetAlumno(la.Buscar(numero)); c = lc.GetCurso(lc.Buscar(sigla)); Console.WriteLine("El alumno {0} {1} se inscribió en el curso {2} ({3})", a.Nombre, a.Apellido, c.Sigla, c.Descripcion); return(new Inscripcion(sigla, numero, semestre)); } static int Menu(string[] opciones) { int contador = 1, op = 0; foreach(string opcion in opciones)

Console.WriteLine("{0}) {1}",contador++,opcion); Console.Write("Ingrese su opción: "); do op = int.Parse(Console.ReadLine()); while (op<=0 && op>=contador); return(op); } static void Main() { string[] opciones = { "Agregar Alumno", "Agregar Curso",

Page 26: Archivos y BD en C Sharp

intro. Prog. Orientada a Objeto – Archivos y B. de Datos Rodrigo Sandoval U.

IIC 1102 Página: 25

"Inscribir en Curso", "Mostrar Alumnos", "Mostrar Cursos", "Mostrar Inscripciones",

"Salir" }; int opcion = 0; const string archivocursos = "cursos.dat"; const string archivoalumnos = "alumnos.dat"; const string archivoinscripciones = "inscripciones.dat"; ListaCursos lc = new ListaCursos(archivocursos); ListaAlumnos la = new ListaAlumnos(archivoalumnos); ListaInscripciones li = new ListaInscripciones(archivoinscripciones); do { opcion = Menu(opciones); switch(opcion) { case 1: la.Agregar(NuevoAlumno()); break; case 2: lc.Agregar(NuevoCurso()); break; case 3: li.Agregar(NuevaInscripcion(la,lc));break; case 4: la.Mostrar(); break; case 5: lc.Mostrar(); break; case 6: li.Mostrar(la,lc); break; } } while(opcion!=7); lc.Guardar(); la.Guardar(); li.Guardar(); } }

Instrucciones de compilación.

Para compilar este ejemplo, se debe copiar el código en un archivo .cs y compilarlo individualmente. En este proceso aparecerán 3 warnings relacionados los bloques try-catch de los constructores de las listas definidas, en específico, indicando que la variable ‘e’ no es utilizada. Se puede modificar ese bloque para utilizarla como parte de un mensaje adecuado, pero no es necesario en estricto rigor.

Instrucciones de ejecución.

Para ejecutar correctamente este ejemplo, los archivos alumnos.dat, cursos.dat, e inscripciones.dat deeben estar ubicados en la misma carpeta del ejecutable, o bien no existir, y serán creados en dicha ubicación.