archivos java

32
Archivos Java - Presentation Transcript 1. Escritura y Lectura de Archivos o Temas o Primeras Consideraciones o Escritura o Lectura o Consejo 2. Primeras Consideraciones o Lo primero a tener en cuenta es hacer la validacion de si el archivo existe o no. o File f=new File(”mi_archivo.txt”); o if (f.exists()) { //aqui pondremos el codigo para leer o escribir o } o Para trabajar con archivos deben recordar importar la clase IO. o Import java.io.*; 3. Escritura o File f=new File(”mi_archivo.txt”); o FileWriter fw= new FileWriter(f, false ); o fw.write(”texto”); o fw.close(); o La unica consideracion es en el codigo en rojo, teniendo 2 alternativas: o false: borra el contenido del archivo y recien escribe o true: agrega el contenido al final (no borra nada) 4. Lectura o String texto=””; o FileReader fr = new FileReader(”mi_archivo.txt”); o BufferedReader lector = new BufferedReader(fr); o String s; o while((s = lector.readLine()) != null){ texto += s + ” ”; o } o System.out.println(texto); Bucle que lee linea a linea hasta el final del archivo En la variable texto tendremos todo el archivo completo. En la varibale 's' tendremos cada linea que se va leyendo 5. Consejos o Para evitar que el programa se 'muera' es recomndable el uso de un Try-Catch: o try{ //aqui el codigo para leer o escribir o } catch(IOException e){ System.out.println(”error”);

Upload: raquel-arevalo

Post on 05-Dec-2014

50 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Archivos Java

Archivos Java - Presentation Transcript

1. Escritura y Lectura de Archivos o Temas o Primeras Consideraciones o Escritura o Lectura o Consejo

2. Primeras Consideraciones o Lo primero a tener en cuenta es hacer la validacion de si el archivo existe o no. o File f=new File(”mi_archivo.txt”); o if (f.exists()) {

//aqui pondremos el codigo para leer o escribir o } o Para trabajar con archivos deben recordar importar la clase IO. o Import java.io.*;

3. Escritura o File f=new File(”mi_archivo.txt”); o FileWriter fw= new FileWriter(f, false ); o fw.write(”texto”); o fw.close(); o La unica consideracion es en el codigo en rojo, teniendo 2 alternativas: o false: borra el contenido del archivo y recien escribe o true: agrega el contenido al final (no borra nada)

4. Lectura o String texto=””; o FileReader fr = new FileReader(”mi_archivo.txt”); o BufferedReader lector = new BufferedReader(fr); o String s; o while((s = lector.readLine()) != null){

texto += s + ” ”; o } o System.out.println(texto);

Bucle que lee linea a linea hasta el final del archivo En la variable texto tendremos todo el archivo completo. En la varibale 's' tendremos cada linea que se va leyendo

5. Consejos o Para evitar que el programa se 'muera' es recomndable el uso de un Try-Catch: o try{

//aqui el codigo para leer o escribir o }

catch(IOException e){ System.out.println(”error”);

o } 6. Creditos o Eduardo Federico Santillan (Perro) o UCASAL OSUM o Mas informacion sobre el tema en: o http://lenguajes-x.com.ar/?cat=14

Page 2: Archivos Java

// Crea un archivo de acceso aleatorio, escribiendo 100 registros vacíos en el disco.

2 import java.io.*;

3 import javax.swing.*;

4

5 public class CrearArchivoAleatorio {

6

7 private static final int NUMERO_REGISTROS = 100;

8

9 // permitir al usuario seleccionar el archivo a abrir

10 private void crearArchivo()

11 {

12 // mostrar cuadro de diálogo para que el usuario pueda seleccionar el archivo

13 JFileChooser selectorArchivo = new JFileChooser();

14 selectorArchivo.setFileSelectionMode( JFileChooser.FILES_ONLY );

15

16 int resultado = selectorArchivo.showSaveDialog( null );

17

18 // si el usuario hizo clic en el botón Cancelar del cuadro de diálogo, regresar

19 if ( resultado == JFileChooser.CANCEL_OPTION )

20 return;

21

22 // obtener el archivo seleccionado

23 File nombreArchivo = selectorArchivo.getSelectedFile();

24

25 // mostrar error si el nombre del archivo es inválido

26 if ( nombreArchivo == null || nombreArchivo.getName().equals( "" ) )

Page 3: Archivos Java

27 JOptionPane.showMessageDialog( null, "Nombre de archivo incorrecto",

28 "Nombre de archivo incorrecto", JOptionPane.ERROR_MESSAGE );

29

30 else {

31

32 // abrir el archivo

33 try {

34 RandomAccessFile archivo =

35 new RandomAccessFile( nombreArchivo, "rw" );

36

37 RegistroCuentasAccesoAleatorio registroEnBlanco =

38 new RegistroCuentasAccesoAleatorio();

39

40 // escribir 100 registros en blanco

41 for ( int cuenta = 0; cuenta < NUMERO_REGISTROS; cuenta++ )

42 registroEnBlanco.escribir( archivo );

43

44 archivo.close(); // cerrar el archivo

45

46 // mostrar mensaje indicando que el archivo se creó

47 JOptionPane.showMessageDialog( null, "Se creó el archivo " +

48 nombreArchivo, "Estado", JOptionPane.INFORMATION_MESSAGE );

49

50 System.exit( 0 ); // terminar el programa

51

52 } // fin del bloque try

Page 4: Archivos Java

53

54 // procesar excepciones durante operaciones de apertura, escritura o cierre del archivo

55 catch ( IOException excepcionES ) {

56 JOptionPane.showMessageDialog( null, "Error al procesar el archivo",

57 "Error al procesar el archivo", JOptionPane.ERROR_MESSAGE );

58

59 System.exit( 1 );

60 }

61

62 } // fin de instrucción else

63

64 } // fin del método crearArchivo

65

66 public static void main( String args[] )

67 {

68 CrearArchivoAleatorio aplicacion = new CrearArchivoAleatorio();

69 aplicacion.crearArchivo();

70 }

71

72 } // fin de la clase CrearArchivoAleatorio

73

74 //casidiablo

Page 5: Archivos Java

Excepciones y Archivos

Excepciones

El término excepción se utiliza cuando algo salió mal, es decir, cuando ocurrió un error. Como seguramente usted  sabe, existe un gran número de situaciones por la que el software puede fallar, pero el software de buena calidad debe de enfrentar esos problemas de manera satisfactoria.

En Java una excepción es un objeto que define una situación inusual o un error.

Cuando se crean sistemas de software y de hardware, la mayoría se encuentra en forma de elementos empacados, por ejemplo, tarjetas de circuitos, clases y métodos de Java. Para simplificar el proceso de diseño, es esencial tratar estos elementos como encapsulados, de tal forma que no es necesario preocuparse de cómo funcionan internamente, pero si es necesario que informen a nuestro software sobre las situaciones de error.

Los sistemas complejos constan de una jerarquía de métodos y algunas excepciones pueden manejarse de forma local en el método que ocurren, y en algunos otros casos pueden pasarse a métodos de nivel más alto, por supuesto todo depende de la naturaleza del error. Así, existen varias categorías de errores, las cuales pueden ser tratadas en distintos lugares.

Así, un programa puede estar diseñado para procesar las excepciones en tres formas distintas:

No manejarla manejar la excepción cuando ocurre manejar la excepción en algún otro punto del programa

Un ejemplo de un programa que no maneja excepciones es el siguiente:

Page 6: Archivos Java

Donde al ejecutarse el programa se detiene y marca un error, de tal forma que la última sentencia nunca será ejecutada.

En general el código para manejar errores podría ser:

si algoSaleMal    encargarse del problemaotro    situación normal

sin embargo cuando se realizan más acciones el código:

hacerA ( )hacerB ( )hacerC ( )

se convierte en:

hacerA ( )si  A salió mal    encargarse del problema cuando A salió malotro

Page 7: Archivos Java

comienza    hacerB ( )    si B salió mal        encargarse  del problema cuando B salió mal    otro     comienza        hacerC ( )        si C salió mal            encargarse del problema cuando C salió mal     terminatermina

Ya que no se espera que los casos de error ocurran muy a menudo, Java ofrece apegarnos a la codificación para el caso normal, y manejar las excepciones en un área separada del programa.

Las excepciones en Java son objetos, por lo que es necesario utilizar el operador new para crear una instancia de una clase apropiada de excepciones.

Para indicar que ha ocurrido una excepción, se dice que se ha lanzado y cuando se detectan en cualquier otra parte, se dice que son atrapadas. Java tiene las palabras clave:

throws throw try catch

para llevar a cabo estas tareas.

Ejemplo:

/** * Aplicación para duplicar un entero dado por el usuario * Sin manejo de excepciones *  * Adaptado de Bell & Parr, Java para estudiantes, Prentice-Hall, 2003 */public class ApliD1{

   public static void main()   {      // crear objetos      System.out.print ("Dame un entero: ");      int entrada = Teclado.readInt ();

      System.out.print("El número duplicado es: ");      int salida = 2*entrada;  }}

Page 8: Archivos Java

En caso de no introducir un entero se produce el siguiente error:

Por supuesto este mismo ejemplo puede crearse como un applet:

import java.awt.*;import java.awt.event.*;import java.applet.*;

/** * Applet para duplicar un entero dado por el usuario * Sin manejo de excepciones *  * Adaptado de Bell & Parr, Java para estudiantes, Prentice-Hall, 2003 */public class D1 extends Applet implements ActionListener{

// Datos miembro

   private TextField   entrada,                        salida;    private Label       etiqueta,                        resultado;

/****************   Constructor****************/

   public D1()   {      // crear objetos      etiqueta = new Label("Dame un entero: ");      entrada  = new TextField(30);

      resultado = new Label("El número duplicado es: ");      salida = new TextField(30);

                            //la salida no es editable        salida.setEditable (false);                            // añade objetos al applet        add (etiqueta);        add (entrada);

Page 9: Archivos Java

        entrada.addActionListener (this);        add (resultado);               add (salida);   }

/* Si no es entero el programa marca un error*/

   public void actionPerformed(ActionEvent event)   {        if (event.getSource () == entrada)        {            int num = Integer.parseInt (entrada.getText ());            salida.setText ( "¡" +(2*num)+ "! ");        }   }}

y entonces usted puede ejecutarlo desde el servidor:

D1

También se puede utilizar el enunciado try-catch para que se se informe al usuario en caso de introducir algo que no fuera un entero:

import java.awt.*;import java.awt.event.*;import java.applet.*;

/** * Applet para duplicar un entero dado por el usuario * Con manejo de excepciones utilizando try-catch *  * Adaptado de Bell & Parr, Java para estudiantes, Prentice-Hall, 2003 */public class Demo1 extends Applet implements ActionListener{

// Datos miembro

   private TextField   entrada,                        salida;    private Label       etiqueta,                        resultado;

/****************   Constructor****************/

   public Demo1()   {      // crear objetos      etiqueta = new Label("Dame un entero: ");      entrada  = new TextField(30);

      resultado = new Label("El número duplicado es: ");

Page 10: Archivos Java

      salida = new TextField(30);

                            //la salida no es editable        salida.setEditable (false);                            // añade objetos al applet        add (etiqueta);        add (entrada);        entrada.addActionListener (this);        add (resultado);               add (salida);   }

/* Se utiliza el enunciado try-catch para la entrada.  * Si no es entero marca un mensaje de error*/

   public void actionPerformed(ActionEvent event)   {        if (event.getSource () == entrada)        try        {            int num = Integer.parseInt (entrada.getText ());            salida.setText ( "¡" +(2*num)+ "! ");        }        catch (NumberFormatException e)        {            salida.setText ("Error en el número: vuelva a escribirlo ");        }   }}

que al ejecutarlo con un "error" nos produce un mensaje adecuado: Demo1

La parte clave del programa es:

            try        {            int num = Integer.parseInt (entrada.getText ());            salida.setText ( "¡" +(2*num)+ "! ");        }        catch (NumberFormatException e)        {            salida.setText ("Error en el número: vuelva a escribirlo ");        }

que es donde si algo sale mal en parseInt  se ejecutará el código que está dentro del catch

La estructura de control try-catch tiene la siguiente forma:

try{    enunciados}catch (AlgunaExcepción e)

Page 11: Archivos Java

{    enunciados}

y Java tratará de ejecutar el bloque de enunciados dentro del try, si no ocurre ninguna excepción, se ignorará el bloque de enunciados dentro del catch y si se produce una excepción del bloque try, entonces se puede ejecutar el bloque catch especificándo el tipo de excepción que se quiere tratar. Si ocurre un tipo que no está especifícado entonces no se ejecutará el bloque catch.

Recuerde que las variables declaradas dentro de un bloque existen dentro de él y no fuera de él, de tal forma que si declara una variable dentro del bloque try, no podrá utilizarla dentro del bloque catch. Por supuesto que una solución a este problema es declarar dicha variable fuera y antes de estos bloques.

Ejercicios:

1. Escriba una aplicación que lea dos enteros y muestre el resultado de a/b. Después incorpore el manejo de excepciones de tal forma que se muestre un mensaje cuando no se introduzcan números enteros.

2. Escriba un applet que introduzca una cadena que represente una fecha de la forma MM/DD/AA por ejemplo 20/03/04, use la clase StringTokenizer para dividirla y producir un mensaje de error si un elemento no es numérico, si no se encuentra o si se especifica una fecha imposible. Ignore los años bisiestos.

Propagación de excepciones

El uso de métodos en tiempo de ejecución es jerárquico (un método de nivel superior invoca a los métodos de nivel inferior, etc.) y este patrón de llamadas es impredecible antes del tiempo de ejecución, ya que la decisión sobre si se va a invocar o no a un método podría ser parte de una instrucción de selección, con base en los datos de entrada.

Imagine que el métodoA llama al métodoB, que a su vez llama al métodoC, la búsqueda de un bloque catch apropiado comienza en métodoC. Si no se encuentra uno, la búsqueda avanza hacia el métodoB. Si este método no cuenta con un bloque catch, entonces la búsqueda avanza hacia el métodoA, y si el método de nivel superior no cuenta con un bloque catch, se muestra un mensaje de excepción. Si el programa es un applet, continuará ejecutándose (o al menos tratará de hacerlo) y sus resultados no serán confiables.

Si una excepción no se atrapa cuando ocurre, entonces se propaga al método que lo mandó llamar.

Page 12: Archivos Java

Ejemplo:

Considere las siguientes dos clases:

/** * Demuestra la propagación de excepciones *  * Adaptado de Lewis & Loftus */public class Propagación{    public static void main (String [] args)    {        AmbitoExcepción demo = new AmbitoExcepción ();        System.out.println ("Inicio del programa");        demo.nivel1 ();        System.out.println ("Fin del programa");    }}

/** * Demuestra la propagación de excepciones *  * Adaptación de Lewis & Loftus */public class AmbitoExcepción{            //Atrapa y maneja excepciones     void nivel1 ()     {         System.out.println ("Nivel 1, inicio");         try         {             nivel2 ();         }         catch (ArithmeticException problema)         {             System.out.println ();             System.out.println ("El mensaje de la excepción es: " + problema.getMessage ());             System.out.println ();             System.out.println ("Llamadas en la pila");             problema.printStackTrace ();             System.out.println ();         }         System.out.println ("Nivel 1, final");     }            //Sirve como nivel intermedio. La excepción se propaga a través de nivel1     void nivel2 ()     {         System.out.println ("Nivel 2, inicio");         nivel3 ();

Page 13: Archivos Java

         System.out.println ("Nivel 2, final");     }                 //Realiza un calculo que produce una excepción, que no se maneja en este nivel     void nivel3 ()     {         int num = 10, den = 0;                  System.out.println ("Nivel 3, inicio");         int result = num/den;         System.out.println ("Nivel 3, final");     }}

Que al ejecutarse produce la siguiente salida:

Page 14: Archivos Java

Jerarquía de las excepciones

java.lang.Object | +--java.lang.Throwable | +--java.lang.Exception | +--java.lang.RuntimeException

ArithmeticException, ArrayStoreException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException,

Page 15: Archivos Java

IllegalPathStateException, IllegalStateException, ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFormatException, SecurityException, SystemException, UndeclaredThrowableException, UnsupportedOperationException

finally

La sentencia finally permite colocar código en un sólo lugar que se ejecutará ya sea después de una excepción, o después de la correcta ejecución del bloque try. Su sintáxis es:

try{    // se realiza si no existe ninguna excepción}catch (Exception){    //se ejecuta cuando existió algún error o situación no prevista}finally{    //se ejecuta si se ejecutó el try o el catch}

Considere el caso en el que un programa abre un archivo correctamente pero encuentra un error al leer de ese archivo. Una acción correctiva deseable sería cerrar el archivo. Al leer una línea (un valor String) de un archivo se puede producir una excepción IOException, y así la lógica para leer una seríe de líneas sería.

String línea;try{    while (línea = archivo.readLine () != null)    {        //procesar línea    }}catch (IOException e){    error.setText ("Error en entrada");}finally{    archivo.close ();}

Archivos

Page 16: Archivos Java

Algunas de las diferencias ente la RAM (memoria de acceso aleatorio) y los dispositivos de almacenamiento externo (discos, CD, stikers) son:

El tiempo requerido para tener acceso a un elemento en la RAM es mucho menor El costo de la RAM es mayor Los datos almacenados en la RAM son temporales. Los dispisitivos de

almacenamiento externo pueden guardar los datos de manera semi-permanente La RAM se utiliza para guardar los programas al ser ejecutados. Éstos se copian de

un dispositivo de almacenamiento externo inmediatamente antes de la ejecución Normalmente la capacidad de los dispositivos de almacenamiento externo es mayor

 Una tarea común en programación es leer y escribir archivos. La información almacenada en un archivo pueden ser datos byte o caracteres (texto), y pueden ser leidos en la misma forma.

Java cuenta aproximadamente con 20 clases para el acceso a archivos, cada una con su propio conjunto específico de métodos. Una decisión importante radica en elegir entre el acceso de flujo y el acceso aleatorio.

Al utilizar el acceso de flujo en un archivo, se debe tratar como una secuencia de elementos que deben ser procesados uno tras otro, empezando con el primero.

Para muchas tareas, esto es completamente inapropiado. El acceso aleatorio permite accesar uno posición espcífica en el archivo. En estas aplicaciones (como las bases de datos) esto puede agilizar el procesamiento, pero también es más complicado de programar. En realidad es probable que se utilice una biblioteca de clase de bases de datos en ez de codificar el acceso de bajo nivel al disco.

Por esta razón nos enfocaremos en los flujos.

Los applets, pueden descargarse de un sitio remoto y se ejecutan dentro de un navegador. No obstante, hay un problema relacionado con la seguridad, el applet puede contener errores o tal vez haya sido escrito con malicia. Una de las áreas clave a las que pueden dirigirse los applets maliciosos es a la eliminación de archivos, de tal forma que se podrían crear applets que eliminaran todos los archivos de una computadora. Por esta razón, los navegadores geeneralmente se configuran para evitar que los applets tengan acceso a los archivos del equipo en los que se ejecutan. Sin embargo, pueden tener acceso a los archivos en el servidor del que fueron descargados. Así, si se desea escribir programas que tengan acceso a archivos, se deben escribir aplicaciones y no applets.

La posible excepción a lo anterior es el crecimiento de los sistemas intranet, que utilizan tecnología WWW pero están restringidos a que puden utilizarse solamente dentro de una organización. En esta situación, podría considerarse el uso de applets confiables.

Page 17: Archivos Java

Archivos de texto

Si se desea procesar datos de un archivo exsitente, se debe:

1. Abrir el archivo 2. Leer o introducir los datos en las variables, un elemento a la vez 3. Cerrar el archivo cuando se termine de trabajar con él

Para transferir algunos datos de ciertas variables a un archivo, se debe:

1. Abrir el archivo 2. Extraer o escribir los elementos en la secuencia requerida 3. Cerrar el archivo cuando se termine de trabajar con él

Al leer un archivo, todo lo que puede hacerse es leer el siguiente elemento. Si, por ejemplo, quisiéramos examinar el último elemento, tendríamos que codificar un ciclo para leer cada uno de los elementos en turno, hasta llegar al elemento requerido. Para muchas tareas, es conveniente visualizar un archivo como una serie de líneas de texto, cada una compuesta por un número de caracteres y que termina con el carácter de fin de línea. Un beneficio de esta forma de trabajo es la facilidad de transferir archivos entre aplicaciones. Así se podría crear un archivo ejecutando un programa en Java y después cargarlo en un procesador de palabras, editor de texto o correo electrónico.

Las clases de flujo están organizadas de la siguiente forma:

Reader    BufferedReader    InputStreamReader        FileReader

Writer    PrintWriter        FileWriter

Para procesar archivos se utilizan las clases BufferedReader y PrintWriter para leer y escribir líneas de texto, y para la entrada que no provenga de archivos (desde el teclado y páginas Web) también se utiliza InputSreamReader.

Los programas que utilizan archivos deben contener la instrucción: import java.io.*;

"Búfer" significa que, el software lee un gran trozo de datos del dispositivo de almacenamiento externo y lo guarda en la RAM, de tal forma que invocaciones sucesivas de los métodos que necesitan leer una pequeña cantidad de datos del dispositivo de almacenamiento de archivos puedan obtener rápidamente los datos de la RAM. Por lo tanto, un búfer actúa como un amortiguador entre el dispositivo de almacenamiento y el programa.

Page 18: Archivos Java

Escribir un archivo de texto requiere el uso apropiado de clases para crear el flujo de salida y llamar a los métodos para escribir los datos. La clase FileWriter representa un archivo texto de salida. La clase PrintWriter ofrece los métodos print y println similares a los de System. Después de terminar de crear o utilizar un archivo es muy recomendable que se cierre, ya que de lo contrario no se garantiza que los datos estarán almacenados en un dispositivo semi-permanente.

Por ejemplo, suponga que desea generar un archivo de prueba que contenga números enteros aleatorios.

import java.io.*;

/** * Demuestra el uso de un archivo texto de salida *  * Adaptación Lewis & Loftus */public class PruebaDatos{                //throws se utiliza cuando no desean manejarse las excepciones    public static void main (String [] args) throws IOException    {        final int MAX = 10;                int valor;        String arch = "prueba.dat";                FileWriter fw = new FileWriter (arch);        BufferedWriter bw = new BufferedWriter (fw);        PrintWriter salArch = new PrintWriter (bw);                for (int i = 1; i <= MAX; i++)        {            for (int n = 1; n <= MAX; n++)            {                valor = (int) (Math.random () * 100);                salArch.print (valor + " ");            }            salArch.println ();        }                    //se cierra el archivo        salArch.close ();        System.out.println ("El archivo de salida ha sido creado: " + arch);    }}

Ejercicio:

Page 19: Archivos Java

Ejecute la clase PruebaDatos y abra el archivo "prueba.dat" creado.

La clase FileReader representa un archivo de entrada que contiene caracteres. Su constructor inicializa la relación entre el programa y el archivo, abriendo un stream (flujo) a partir del cual se leeran los datos.

La siguiente clase permite leer el archivo "prueba.dat" utilizando las clases FileReader y BufferReader:

import java.io.*;

/** * Demuestra el uso de un archivo de texto *  */public class ChecaDatos{    public static void main (String [] args) throws IOException    {        String arch = "prueba.dat";        String línea;                             //Creación del lector de archivo        FileReader fr = new FileReader (arch);                    //Para manejo de entrada;        BufferedReader entArch = new BufferedReader (fr);                    //Se lee la primera línea        línea = entArch.readLine ();        while (línea != null)        {            System.out.println (línea + "\n");            línea = entArch.readLine ();        //Se lee una nueva línea        }        entArch.close ();    }}

Estas mismas clases (FileReader y BufferedReader) se pueden utilizar para manejo de objetos. Por ejemplo considere las siguentes dos clases: Cosa e Inventario:

import java.text.DecimalFormat;

/** * Representa el objeto de un inventario *  * Adaptación Lewis & Loftus */public class Cosa{    private String nombre;    private int unidades;

Page 20: Archivos Java

    private float precio;    private DecimalFormat fmt;        Cosa (String n, int u, float p)    {        nombre = n;        unidades = u;        precio = p;        fmt = new DecimalFormat ("0.##");    }        public String toString ()    {        return nombre + ":\t" + unidades + " a $" + precio + " = " +                fmt.format ((unidades * precio));     } }

import java.util.StringTokenizer;import java.io.*;

/** * Demuestra el uso de un archivo de caracteres como stream de entrada *  * Adaptación Lewis & Loftus */public class Inventario{    public static void main (String [] args)    {        final int MAX = 100;        Cosa [] items = new Cosa [MAX];        StringTokenizer tokenizer;        String línea, nombre, arch = "inventario.dat";        int unidades, cuenta = 0;        float precio;                try        {            FileReader fr = new FileReader (arch);            BufferedReader archEnt = new BufferedReader (fr);                        línea = archEnt.readLine ();            while (línea != null)            {                tokenizer = new StringTokenizer (línea);                nombre = tokenizer.nextToken ();                try                {                    unidades = Integer.parseInt (tokenizer.nextToken ());                    precio = Float.parseFloat (tokenizer.nextToken ());                    items [cuenta++] = new Cosa (nombre, unidades, precio);                }                catch (NumberFormatException exc)                {                    System.out.println ("Error en la entrada. Linea

Page 21: Archivos Java

ignorada");                    System.out.println (línea);                }                línea = archEnt.readLine ();            }            archEnt.close ();                        for (int s = 0; s < cuenta; s++)                System.out.println (items [s]);         }         catch (FileNotFoundException exc)         {             System.out.println ("El archivo " + arch + " no fue encontrado ");         }         catch (IOException exc)         {             System.out.println (exc);         }     } }

Cuya salida es:

Ejercicio escriba una clase que permita escribir el archivo inventario.dat anterior con al menos 5 objetos.

La clase File

Esta clase ofrece la capacidad de manipular archivos y directorios en general.

No se utiliza para tener acceso a los datos dentro de los archivos.

Se necesita utilizar la instrucción: import java.io.*;

La mayoría de los sistemas operativos ofrecen una estructura jerárquica con una ruta para avanzar a través de la misma, cuya forma es:

Page 22: Archivos Java

d:\estructuraDeDatos\Java\Archivos\Inventario.java

Ésta es una ruta estilo Windows que utiliza '\' como separador. En un sistema UNIX se utiliza como separador '/'. Si usted necesita escribir software para manipular rutas y que funcione en cualquier sistema puede averiguar cúal es el separador de archivos haciendo referencia a la constante de la cadena File.separator.

La ruta mostrada anteriormente es absoluta, empieza desde la parte superior del directorio y lo lleva hasta el archivo. No obstante, a veces esto es irrelevante: sólo necesitamos tratar con rutas que sean relativas al directorio actual. Por ejemplo, si nos encontramos en el directorio Java, entonces la ruta de Inventario.java sería Archivos\Inventario.java.

Inicialmente debemos construir una instancia de la clase File proporcionando una cadena. Una vez creada se puede utilizar. Considere la siguiente instrucción:

File archivo = new File ("c:\\estructuraDeDatos\\Java\\Archivos\\Inventario.java");

Como el caracter de escape '\' es casualmente el mismo que el separador de archivos en Window, se necesita decir que es simplemente un caracter normal de la cadena en vez de tener un significado especial, por lo que hay que anteponerle un caracter de escape. Así, \\ representa a \.

Función Ejemplo

getPathEncuentra la ruta relativa

String relativa = archivo.getPath( );Devuelve "Inventario.java"

getAbsolutePathEncuentra la ruta absoluta

String absoluta = archivo.getAbsolutePath ( );Devuelve "c:\estructuraDeDatos\Java\Archivos\Inventario.java"

existsComprueba que el archivo exista

boolean existe = archivo.exists ( );Devuelve true o false

isDirectoryComprueba si es un directorio

boolean comprobarDirectorio = archivo.isDirectory ( );Devuelve true si el archivo es un directorio y false en otro caso

lengthTamaño del archivo en

long longitud = archivo.length ( );

Page 23: Archivos Java

bytes

listLlena un arreglo de cadeas con la lista de los nombres de los archivos que hay dentro de un directorio

String [ ] todosLosArchivos = archivo.list ( );Como "Inventario.java" no es un directorio regresaría null

Ejemplo:

MiniNavegador

Ejercicios:

1. Cree una aplicación que lea de teclado una oración dada por el usuario y que ésta se escriba en un archivo.

2. Cree una apliación para mostrar directorios en una lista, que pida al usuario una ruta absoluta y luego muestre todos los nombres de archivos que haya dentro de ese directorio. Si alguno de los archivos es un directorio, debe imprimirse la palabra "dir" después de su nombre.

Serialización

Cuando un programa termina, los datos usados se destruyen a menos que se almacenen de manera externa.

¿qué pasa cuando se desea almacenar un objeto, un arreglo de objetos o alguna estructura compleja?

Se puede escribir código que almacene todas las piezas del objeto de forma separada y después reconstruir el objeto con esa información, pero esto es un proceso tedioso.

La persistencia  permite que un objeto pueda "vivir" separado de la ejecución del programa que lo construyó. Java posee un mecanismo para crear objetos persistentes llamado serialización de objetos.

Page 24: Archivos Java

Un objeto se serializa transformándolo en una secuencia de bytes que representan al objeto. Posteriormente esta información puede restablecerse. Una vez serializado el objeto puede almacenarse en un archivo o transmitirse por la red.

Un objeto que desea serializarse debe tener la interface Serializable, que sirve como bandera al compilador. Para serializar un objeto se invoca al método writeObject de ObjectOutputStream. Para deserializar un objeto se invoca al método readObject de ObjetInputStream.

Por ejemplo, suponga la clase coche implementada como serializable y que se desea almacenar en un archivo. Para hacer esto, debe crearse un FileOutputStream y envolverlo en un ObjectOutputStream:

FileOutputStream salArch = new FileOutputStrem ("info.dat");ObjectOutputStream salStream = new ObjectOutputStream (salArch);

para serializar el objeto se involca al método writeObject:

salStream.writeObject (miCoche);

Para invertir el proceso, primero se crea un flujo (stream de entrada):

FileInputStream entArch = new FileInputStream ("info.dat");ObjectInputSteam entStream = new ObjectInputStream (entArch);

para leer y deserializar el objeto:

Coche c = (Coche) entStream.readObject ();

El método readObject regresa una referencia a un Object, por lo que debe de realizarse un cast a la clase apropiada.

Ejemplo:

Considere la clase Coche, para guardar en un archivo objetos de tipo coche se utiliza la clase EscribeArchivoCoches y  para leer de archivo objetos de tipo coche se utiliza LeeArchivoCoches .

Ejercicios:

1. Ejecúte EscribeArchivoCoches y LeeArchivoCoches. Después inserte algún otro objeto de tipo coche y vea que sucede

2. Modifique EscribeArchivoCoches y LeeArchivoCoches, para que manejen excepciones a través de try-catch.

Page 25: Archivos Java

3. Construya un directorio de sus amigos. Considere que la información más relevante para representar a un amigo es: nombre, teléfono, correo-e y fecha de cumpleaños. Utilice objetos serializables para escribir y leer de archivo. (Para entregar)

Compresión

La biblioteca de E/S de Java tiene clases que dan soporte a la lectura y escritura de flujos en formato comprimido. Son parte de las jerarquías InputStream y OutputStream.

Aunque existen muchos algoritmos de compresión, los más comunes son ZIP y GZIP.

El uso de clases de compresión es directo, simplemente se envuelve el flujo de salida en un GZIPOutputStream o en un ZipOutputStream, y el flujo de entrada en un GZIPInputStream o en un ZipInputStream. Todo lo demás es lectura y escritura de E/S ordinarias.

Compresión con GZIP

Es apropiada para comprimir un único flujo de datos.

Ejemplo: CompresiónGZIP

Almacenamiento múltiple con ZIP

La biblioteca que soporta ZIP es más completa. Con ella, es posible almacenar de manera sencilla múltiples archivos, además se puede calcular y verificar la suma de comprobación del archivo a través de las clases Chechsum. Hay dos tipos de Chechsum: Adler32, más rápido y CRC32, más lento pero ligeramente más exacto.

Para cada archivo que se desee añadir  es necesario llamar a putNextEntry () y pasarle un objeto ZipEntry. Este objeto contiene una interfaz que permite extraer y modificar todos los datos disponibles en esa entrada particular del archivo ZIP: nombre, tamaño comprimido y descomprimido, fecha, suma de comprobaciónCRC, datos de campo extra, comentarios, métodos de compresión y si es o no una entrada de directorio. Sin embargo, incluso aunque el formato ZIP permite poner

Page 26: Archivos Java

contraseñas a los archivos, no hay soporte para esta faceta en la bilbioteca ZIP de Java. Y aunque tanto CheckedInputStream como CheckedOutputStream soportan ambos sumas de comprobación, Adler32 y CRC32,  la clase ZipEntry sólo soporta una interfaz para CRC.

Para extraer archivos, ZipInputStream tiene un método getNextEntry () que devuelve la siguiente ZipEntry si es que la hay. Otra alternativa es usar un objeto ZipFile, que tiene un método entries () para devolver una Enumeration al ZipEntries.

Para leer la suma de comprobación hay que tener algún tipo de acceso al objeto Checksum asociado. Aquí, se retiene una referencia a los objetos CheckedOutputStream y CheckedInputStream, pero también se podría simplemente guardar una referencia al objeto Checksum.

Ejemplo: CompresiónZIP

Recursividad

Aplicaciones recursivas : Cadena                                                 T                                                 Sumatoria

Un applet recursivo: Dibujos