Guia 10 Archivos y Serializacion

41
UNIVERSIDAD NACIONAL MAYOR DE SAN MARCOS Facultad de Ingeniería de Sistemas e Informática GUIA DE PRÁCTICA 9 ASIGNATURA Algorítmica II TEMA PERSISTENCIA PROFESOR Carlos A. Ruiz De La Cruz Melo ALUMNO FECHA CICLO TURNO SEMESTRE 2008-1 1. OBJETIVOS Que el estudiante: Use y manipule los mecanismos de persistencia para registrar la información java 2. INTRODUCCION TEORICA Normalmente, cuando se codifica un programa, se hace con la intención de que el program pueda interactuar con los usuarios del mismo, es decir, que el usuario pueda pedirle q determinada tarea, suministrándole datos con los que debe llevar a cabo la tarea solici espera que el programa los manipule de alguna forma, proporcionando una resp solicitado. Por otra parte, en muchas ocasiones interesa que el programa guarde los datos que se le introducido, de forma que al finalizar el proceso, los datos no se pierdan y puedan ser en una sesión posterior. La forma habitual de hacer esto es mediante la utilización de de almacenamiento secundario o externo (normalmente un disco). Se llama persistencia a la capacidad de una entidad de trascender el tiempo o el espacio. E programación previa al paradigma de objetos estaba representada con la entrada y salida datos. Es un concepto importante, pues permite que un objeto pueda ser usado en diferen momentos 2.1. Flujos El modelo más sencillo de un algoritmo consiste en tres conexiones: datos de procesamiento y datos de salida. Entrada y salida ( E / S ) es un aspecto fundamental en la computación. La computadora no sería muy útil si no pudiera recibir datos del mundo exte y presentar los datos computados. En esta sección se describe como Java , a través de java.io y java.nio, y otros paquetes relacionados , proporciona clases independientes para manipular archivos y flujos ( strea Profesor: Carlos A. Ruiz De La Cruz Melo 1

Transcript of Guia 10 Archivos y Serializacion

UNIVERSIDAD NACIONAL MAYOR DE SAN MARCOS Facultad de Ingeniera de Sistemas e Informtica

GUIA DE PRCTICA 9ASIGNATURA TEMA PROFESOR ALUMNO FECHA CICLO TURNO SEMESTRE 1. OBJETIVOS Que el estudiante: Use y manipule los mecanismos de persistencia para registrar la informacin en java Algortmica II PERSISTENCIA Carlos A. Ruiz De La Cruz Melo

2008-1

2. INTRODUCCION TEORICANormalmente, cuando se codifica un programa, se hace con la intencin de que el programa pueda interactuar con los usuarios del mismo, es decir, que el usuario pueda pedirle que realice determinada tarea, suministrndole datos con los que debe llevar a cabo la tarea solicitada. Se espera que el programa los manipule de alguna forma, proporcionando una respuesta a lo solicitado. Por otra parte, en muchas ocasiones interesa que el programa guarde los datos que se le han introducido, de forma que al finalizar el proceso, los datos no se pierdan y puedan ser recuperados en una sesin posterior. La forma habitual de hacer esto es mediante la utilizacin de dispositivos de almacenamiento secundario o externo (normalmente un disco). Se llama persistencia a la capacidad de una entidad de trascender el tiempo o el espacio. En la programacin previa al paradigma de objetos estaba representada con la entrada y salida de datos. Es un concepto importante, pues permite que un objeto pueda ser usado en diferentes momentos

2.1. FlujosEl modelo ms sencillo de un algoritmo consiste en tres conexiones: datos de entrada, procesamiento y datos de salida. Entrada y salida ( E / S ) es un aspecto fundamental en la computacin. La computadora no sera muy til si no pudiera recibir datos del mundo exterior y presentar los datos computados. En esta seccin se describe como Java , a travs de java.io y java.nio, y otros paquetes relacionados , proporciona clases independientes para manipular archivos y flujos ( streams ).

Profesor: Carlos A. Ruiz De La Cruz Melo

1

2.1.2 Los flujos estndarJava al igual que cualquier otro lenguaje de programacin tiene su conjunto mtodos que le permiten captar la informacin de flujos de entrada y enviar flujos de salida por dispositivos estndar. Los flujos estndar son: Flujo de datos de entrada: o Se realiza mediante la clase System.in y suele recibir los datos del teclado o Utiliza el mtodo read() para conseguir leer los caracteres del teclado Flujo de datos de salida: o Se realiza mediante la clase System.out y suele enviar los datos por pantalla o o Utiliza el mtodo print() y println() para la salida por pantalla Se realiza mediante la clase System.err Flujo de datos de error o Nos aseguramos que la salida va redirigida al monitor para enviar mensajes de error al usuario El flujo de entrada ms utilizado esta asociado a el teclado, veamos el siguiente ejemplo que es bastante ilustrativo. /** * Ejemplo: programa de flujos (streams) * que lee tu nombre de la lnea de comandos * y te lo muestra por la consola de salida. * Curso de Java Bsico * @author Oscar A. Gonzlez Bustamante * @version 1.0 * Archivo: HolaOscar.java */

import java.io.*; public class HolaOscar { public static void main(String[] args) throws IOException { InputStreamReader lector = new InputStreamReader(System.in); BufferedReader entrada = new BufferedReader(lector); System.out.print("Cual es tu nombre? "); String nombre = entrada.readLine(); System.out.println("Hola " + nombre + "!"); } }// fin de la clase HolaOscar

Profesor: Carlos A. Ruiz De La Cruz Melo

2

La salida del programa al ejecutarlo con el comando java HolaOscar es: Da tu nombre: Oscarin Hola, Oscarin! En la siguiente figura vemos el proceso de tomar los datos del flujo estndar de entrada System.in asociado al teclado con la creacin del objeto lector de la clase InputStreamReader . Luego con el objeto lector lo utilizamos como argumento del constructor de un objeto entrada de la clase BufferReader , el cual tiene mtodos como readLine() , para leer el conjunto de bytes del buffer hasta el final de la lnea. Finalmente utilizamos el mtodo println() de System.out que esta asociado al flujo estndar de salida para presentar los datos por la consola o monitor.

2.1.2.1 Algunos ejemplos de flujo estndarEn los ejemplos siguientes, usamos el flujo estndar de entrada System.in asociado al teclado. Todo lo que se lea de algn flujo de entrada esta dado en bytes , los cuales son transformados a cadenas de caracteres. Entonces como hacemos la lectura de algn nmero real o entero por teclado?. Afortunadamente existen mtodos de conversin de cadenas en las clases envoltorio ( wrappers ) como doubleValue() que convierte una cadena en formato de nmero real a una variable primitiva de tipo double. As es como podemos entonces manejar los flujos de datos de bytes o caracteres a formatos binarios

Profesor: Carlos A. Ruiz De La Cruz Melo

3

especficos. Tambin observe que el mtodo main() se esta manejando la excepcin IOException , para preveer algn tipo de error en el flujo de entrada o salida. ver el ejemplo: /** * Ejemplo: programa de flujos (streams) * que lee el valor del radio desde el teclado y calcula * el rea del circulo. La cadena del nmero see lee * con un flujo de entrada que luego es convertido a * formato de nmero de tipo double con doubleValue() * de la clase wrapper Double . El programa calcula el * rea del circulo en base al radio dado y presenta el * resultado por pantalla. * @author Oscar A. Gonzlez Bustamante * @version 1.0 * Archivo: AreaCirculo.java */ import java.io.*; public class AreaCirculo{ public static void main(String[] args) throws IOException { InputStreamReader lector = new InputStreamReader(System.in); BufferedReader entrada = new BufferedReader(lector); System.out.print("Introduce valor del radio: "); String texto = entrada.readLine(); Double x = new Double(texto); double r = x.doubleValue(); System.out.println("El area de un circulo de radio "+ r ); double area = r*r*Math.PI; System.out.println(" es " + area); } }// fin de la clase AreaCirculo Para correr el programa hay que ejecutar la sentencia java AreaCirculo y presenta los siguientes resultados si se le da como radio el valor de 10. Introduce valor del radio: 10 El area de un circulo de radio 10.0 es 314.1592653589793

2.1.3 Los flujos que ofrece java.ioJava ofrece dos clases abstractas para manejar los flujos de datos procedentes de equipos remotos o archivos y son java.io.OutputStream y java.io.InputStream, a continuacin presentamos la jerarqua de estas clases clases . Object o InputStream FileInputStream

Profesor: Carlos A. Ruiz De La Cruz Melo

4

o

FilterInputStream PushbackInputStream BufferedInputStream LineNumberInputStream

o OutputStream

StringBufferInputStream o o ByteArrayInputStream PipedInputStream SequenceInputStream

ByteArrayOutputStream PipedOutputStream FileOutputStream FilterOutputStream o o o PrintStream BufferedOutputStream DataOutputStream

Algunas de estas clases van a aparecer junto con algunos de sus mtodos, en los ejemplos que veremos mas adelante.

2.1.4 Flujos de bytes Para los ejemplos siguientes, supondremos que los objetos de tipo InputStream y OutputStream nos vienen dados, sin preocuparnos de como han sido creados (de hecho, las clases mencionadas ya habamos dicho que son clases abstractas que y no pueden ser instanciadas , as que son la base de otras clases concretas de donde si podemos instanciar objetos ). public abstract class InputStream extends Object Lectura de bytes individuales: Se logra mediante cdigo como:InputStream is= ...; int b = is.read();

As podemos obtener el siguiente byte del InputStream. Hay que darse cuenta que el byte (8 bits) se devuelve como un dato de tipo int (32 bits), con un valor entre 0 y 255. En caso de que se haya alcanzado el final del archivo, el mtodo read() devuelve un valor de -1. Lectura de varios bytes. Primero se crea un arreglo unidimensional del tamao adecuado. El tamao de este arreglo es lo que indica al mtodo read() cuntos bytes debe leer como mximo. El siguiente ejemplo de fragmento de cdigo lee 1024 bytes de un flujo de entrada.byte[] = miArreglo = new byte[1024]; // declaramos el arreglo.

Profesor: Carlos A. Ruiz De La Cruz Melo

5

InputStream is = ...; int lee = is.read(miArreglo);

La variable lee almacena el nmero de bytes que se han ledo en realidad. Si se llega al final del archivo, devuelve el valor de -1. No hay garanta de leer exactamente el nmero de bytes especificado, porque puede ser menor debido a que estamos leyendo de un archivo que se ha acabado, porque los datos de una conexin de red tardan en llegar, o cualquier otra causa. De cualquier forma, cuando el mtodo read() devuelva un valor distinto de -1 podemos seguir leyendo mediante sucesivas llamadas a read(). Veamos el siguiente ejemplo que muestra el uso del mtodo read() para leer bloques de bytes./** * Ejemplo: programa de flujos (streams) * que lee el flujos de bytes. Las cadenas a leer se * almacenan en los arreglos de bytes buffer1 y buffer2. * Ambos tiene un tamao especfico de 20 bytes y * son ledos con el mtodo read(). Luego instanciamos * dos objetos de la clase String con dichos buffers. * Finalmente los enviamos por System.out.println() a * la pantalla o consola de salida, y usamos el mtodo * trim() para eliminar los espacios blancos o vacos. * @author Oscar A. Gonzlez Bustamante * @version 1.0 * Archivo: EscribeNombres.java */ public class EscribeNombres { public static void main(String[] args) { final int LON = 20 ; byte[] buffer1 = new byte[LON]; System.out.print("Introduce tu apellido: "); try { System.in.read(buffer1, 0, LON) ; } catch (Exception e) {} String apellido = new String(buffer1) ; byte[] buffer2 = new byte[LON]; System.out.print("Introduce tu nombre: "); try { System.in.read(buffer2, 0, LON) ; } catch (Exception e) {} String nombre = new String(buffer2) ; System.out.println("Hola , " + nombre.trim() + " " + apellido.trim()); } } // fin de la clase EscribeNombres La salida del programa al ejecutarlo con el comando java EscribeNombres es: Introduce tu apellido: GONZALEZ Introduce tu nombre: OSCAR Hola , OSCAR GONZALEZ Cerrar el flujo de entrada. Cuando ya no necesitamos leer datos de un flujo de entrada, se tienen que liberar los recursos reservados mediante el mtodo close(). Si no cerramos el InputStream explcitamente, el flujo asociado se cierra cuando se destruye el objeto. Escritura de bytes individuales. La clase OutputStream dispone de varios mtodos write(). Ejemplo:

Profesor: Carlos A. Ruiz De La Cruz Melo

6

OutputStream os = ..; int dato = 777; os.write(dato); Como en el caso del mtodo read() de la clase InputStream , el mtodo write() recibe un byte dentro de una variable de tipo int (32 bits). Escritura de varios bytes. El cdigo siguiente es muy ilustrativo. byte[] vector = { 65, 66, 67, 68, 69}; OutputStream os = ...; os.write(vector); // escribe los bytes 65, 66,67,68,69 os.write(vector,1,3); // escribe los bytes 66,67,68

2.1.5 Gestin de excepciones de entrada / salidaTodos los mtodos read(), write() , avaible() , etc. lanzan excepciones de tipo java.io.IOException . Estas excepciones es obligatorio capturarlas, o aparecern errores en tiempo de compilacin. En general, las partes de los programas que trabajen con los flujos deben estar dentro de una clusula try ... catch Ejemplo:

try { InputStream is= ..; while ( ... ) { // Leemos y procesamos datos involucrados con los flujos } }catch(IOException ioe) { System.err.println("Hubo un error al abrir el flujo tal y tal ... "); ioe.printStackTrace(); } En programas pequeos en los que no se quiera complicarse la existencia con estructuras de ste tipo, se puede tomar el camino alternativo de mandar la excepcin "hacia arriba". Por ejemplo: public static void main(String[] args) throws IOException { // programa creado por un programador flojo } El siguiente programa calcula el rea de un tringulo, y hace uso del manejo de excepciones para los flujos de entrada de tipo java.io.IOException en el mtodo lee_doble() . Si al compilar el programa le manda un warning de que el mtodo readLine() esta desaprobado ( deprecated ), no se preocupe mucho por eso, el programa correr, es solo una advertencia del compilador de Java que le invita a ud. a utilizar algn otro mtodo ms actualizado para dicho fin.

Profesor: Carlos A. Ruiz De La Cruz Melo

7

/** * Ejemplo: programa de flujos (streams) * que lee el un flujo de datos por el teclado * y lo convierte a un valor de tipo double. * El programa utiliza manejo de excepciones * de tipo java.io.IOException. * @author Oscar A. Gonzlez Bustamante * @version 1.0 * Archivo: AreaTriangulo.java */ import java.io.DataInputStream; class AreaTriangulo{ static double lee_doble(String msj) { DataInputStream stream = new DataInputStream(System.in); String strng; double aux; // escriba una linea para leer desde el teclado. try { System.out.print(msj); strng = stream.readLine(); } catch ( java.io.IOException e ) { strng = "0.0"; } // tratando de convertir este valor a un valor de tipo double try { aux = Double.valueOf(strng).doubleValue(); } catch ( java.lang.NumberFormatException e) { aux = 0.0; } return aux; } public static void main (String args[] ) { double a,b,c; double s,p; System.out.println("Calcular Area de un triangulo"); a = lee_doble("Dame lado a: "); b = lee_doble("Dame lado b: "); c = lee_doble("Dame lado c: "); System.out.println("a= "+ a + " b = " + b + " c= " + c); p = ( a + b + c ) / 2.0; System.out.println("p= " + p); s = Math.sqrt( p*(p-a) * (p-b) * (p-c) ); System.out.println("Area = " + s ); System.out.println("fin del programa");

Profesor: Carlos A. Ruiz De La Cruz Melo

8

} } // fin de la clase AreaTriangulo La salida del programa al ejecutarlo con el comando java AreaTriangulo es: Calcular Area de un triangulo Dame lado a: 30 Dame lado b: 40 Dame lado c: 50 a= 30.0 b = 40.0 c= 50.0 p= 60.0 Area = 600.0 fin del programa

2.1.6 Flujos de acceso a archivosYa sea para leer o para escribir en un archivo, estos se manipulan con flujos de acceso a archivos. En Java tenemos la clase FileInputStream , con los mtodos necesarios para abrir e interactuar con un canal de comunicacin hacia un archivo de entrada para nuestra aplicacin, y la clase FileOutputStream para el caso de un archivo de salida. La clases FileInputStream y FileOutputStream reciben en uno de sus constructores como parmetro el nombre del archivo a leer o escribir. Hay otras dos variantes: una que recibe un objeto de tipo File y otra que recibe un objeto de tipo FileDescriptor. En la seccin siguiente veremos la primera variante y como se utiliza la clase File para dicho fin.

2.1.7 La clase FileEn el caso de la clase File esta se utiliza para encapsular la interaccin de nuestros programas con el sistema de archivos. Mediante la clase File no nos limitamos a leer el contenido del archivo, como ocurra con la clase FileInputStream, sino que podemos obtener informacin adicional, como el tamao del archivo, su tipo, su fecha de creacin, los permisos de acceso que tenemos con l, etc. Adems, la clase File es la nica forma que tenemos de trabajar con directorios (crearlos, ver los archivos que contienen, cambiar el nombre o borrar los archivos, etc.). La forma ms sencilla de crear un objeto File es: File elArchivo = new File("c:\\cursojava\\elarchivo.txt"); Es muy importante darse cuenta de la diferencia entre un objeto de tipo File y el archivo o directorio al que se refiere. Por ejemplo, el archivo c:\cursojava\elarchivo.txt que aparece en el fragmento de cdigo anterior no tiene porque existir. Para saber si un objeto File se refiere a un archivo existente podemos usar el mtodo exists(), ejemplo: File elArchivo = new File("c:\\cursojava\\elarchivo.txt"); if (elArchivo.exists()) { // El archivo existe }

Profesor: Carlos A. Ruiz De La Cruz Melo

9

else { // El archivo no existe } Se puede obtener ms informacin de un objeto de la clase File, como , el tamao del archivo, si se puede leer el archivo, si se puede escribir en el archivo, si se ha borrado con xito el archivo, si se puede borrar, el nombre de la carpeta donde se encuentra el archivo, etc. Veamos los siguientes fragmentos de cdigo : File f = new File("c:\\cursojava\\elarchivo.txt"); long = f.length(); // tamao del archivo boolean lectura = f.canRead(); // Podemos leer el archivo ? boolean escritura = f.canWrite(); // Podemos escribir el archivo ? if ( f.delete()) { // archivo borrado con xito } else { // el archivo no se ha podido borrrar } String nombre = f.getName(); // Nombre (sin carpeta) del archivo String dir = f.getParent(); // Directorio o carpeta del archivo if ( f.isDirectory() ) { // Es un directorio } else { // No es un directorio } if ( f.isFile() ) { // es un archivo normal } else { // no es un archivo normal } long modificado = f.lastModified(); // Fecha ltima de modificacin o actualizacin if ( f.renameTo( new File("c:\\cursojava\\otroArchivo.txt"))) { // Nombre de archivo modificado } else { // nombre de archivo no modificado } La clase File, tambin nos permite manejar carpetas. Los siguientes fragmentos de cdigo que se muestran a continuacin ejemplifican como se puede trabajar con carpetas o directorios mediante la clase File. File f = new File ("c:\\cursojava");

Profesor: Carlos A. Ruiz De La Cruz Melo

10

String[] lista = f.list(); // obtenemos la lista de archivos for ( int i=0; i < lista.length; i++) // los imprimimos System.out.println("Archivo n " + i + ":" + lista[i]); File t = new File("c:\\cursojava\\ejemplos" ); if ( t.mkdir() ) { // Se ha creado un directorio ejemplos sobre c:\cursojava previamente existente } else { // no se pudo crear el directorio } File w = new File("c:\\cursojava\\alumnitos\\aplicados\\estudiosos\\deJava");

if ( w.mkdirs() ) { /* Se ha creado el directorio deJava junto con los directorios intermedios necesarios. */ } else { /* No se pudo crear el directorio */ }

2.1.7.1 Ejemplos de la clase FileEn este primer ejemplo de la clase File muestra el uso de algunos de sus mtodos para manejo de archivos: /** * Programa de java que ejemplifica el uso * de la clase File, demostrando el acceso a * archivos y carpetas * @autor Oscar A. Gonzlez Bustamante * @version 1.0 * Archivo: FlujoArchivos2.java */ import java.io.*; import java.util.Date; public class FlujoArchivos2 { static String ruta = "C:\\j2sdk141\\ejemplos\\"; static String[] archivos = { new String("Aeropuerto.java"), new String("IncrementoDecremento.java") }; static String archi = archivos[1]; static void prhr(char c, int lim) { for(int i=0; i-----------------------------------------------------------El tamao del archivo:(IncrementoDecremento.java:604 Bytes) Fin del programa

Profesor: Carlos A. Ruiz De La Cruz Melo

13

El segundo ejemplo de la clase File muestra el uso de algunos de sus mtodos para manejo de carpetas o directorios: /** * Programa de java que ejemplifica el uso * de la clase File para demostrar * el manejo de carpetas o directorios * @autor Oscar A. Gonzlez Bustamante * @version 1.0 * Archivo: FlujoArchivos3.java */ import java.io.*; import java.util.Date; public class FlujoArchivos3 { static String ruta = "C:\\j2sdk141\\ejemplos\\E-S\\"; static String[] lista; static void prhr(char c, int lim) { for(int i=0; i