gentoo linux, java, software libre y otras hierbas
feb, 04 2008 - 10:19 am

[código] Leer datos en forma secuencial, de un archivo de acceso aleatorio

En el próximo ejemplo, aprenderemos a leer datos en forma secuencial, de un archivo de acceso aleatorio en Java. Para ello es necesario haber ejecutado (y entendido) los dos ejemplos anteriores: en donde creabamos un archivo de acceso aleatorio, y donde escribiamos sobre dicho archivo.

El resultado…

imagen programa

 

 

imagen programa

El código…

Igual que en ejemplos anteriores usaremos la clase IUBanco.java, que proporciona la estructura básica de la Interfaz Gráfica:

import java.awt.*;
import javax.swing.*;
public class IUBanco extends JPanel
{
	// texto de las etiquetas para la GUI
	protected final static String nombres[] = { "Número de cuenta",
      "Primer nombre", "Apellido", "Saldo", "Monto de la transacción" };

   // componentes de GUI; protegidos para el acceso futuro de las subclases
   protected JLabel etiquetas[];
   protected JTextField campos[];
   protected JButton hacerTarea1, hacerTarea2;
   protected JPanel panelInternoCentro, panelInternoSur;

   protected int tamanio; // número de campos de texto en la GUI

   // constantes que representan a los campos de texto en la GUI
   public static final int CUENTA = 0, PRIMERNOMBRE = 1, APELLIDO = 2,
      SALDO = 3, TRANSACCION = 4;

   // Configurar GUI. El argumento miTamanio del constructor determina el número de
   // filas de componentes de GUI.
   public IUBanco( int miTamanio )
   {
      tamanio = miTamanio;
      etiquetas = new JLabel[ tamanio ];
      campos = new JTextField[ tamanio ];

      // crear etiquetas
      for ( int cuenta = 0; cuenta < etiquetas.length; cuenta++ )
         etiquetas[ cuenta ] = new JLabel( nombres[ cuenta ] );

      // crear campos de texto
      for ( int cuenta = 0; cuenta < campos.length; cuenta++ )
         campos[ cuenta ] = new JTextField();

      // crear panel para distribuir etiquetas y campos
      panelInternoCentro = new JPanel();
      panelInternoCentro.setLayout( new GridLayout( tamanio, 2 ) );

      // adjuntar etiquetas y campos a panelInternoCentro
      for ( int cuenta = 0; cuenta < tamanio; cuenta++ ) {
         panelInternoCentro.add( etiquetas[ cuenta ] );
         panelInternoCentro.add( campos[ cuenta ] );
      }

      // crear botones genéricos; sin etiquetas ni manejadores de eventos
      hacerTarea1 = new JButton();
      hacerTarea2 = new JButton(); 

      // crear panel para distribuir los botones y adjuntarlos
      panelInternoSur = new JPanel();
      panelInternoSur.add( hacerTarea1 );
      panelInternoSur.add( hacerTarea2 );

      // establecer esquema de este contenedor y adjuntarle los paneles
      setLayout( new BorderLayout() );
      add( panelInternoCentro, BorderLayout.CENTER );
      add( panelInternoSur, BorderLayout.SOUTH );

      validate(); // validar esquema 

   } // fin del constructor

   // devolver referencia al botón de tarea genérico hacerTarea1
   public JButton obtenerBotonHacerTarea1()
   {
      return hacerTarea1;
   }

   // devolver referencia al botón de tarea genérico hacerTarea2
   public JButton obtenerBotonHacerTarea2()
   {
      return hacerTarea2;
   }

   // devolver referencia al arreglo campos de objetos JTextField
   public JTextField[] obtenerCampos()
   {
      return campos;
   }

   // borrar el contenido de los campos de texto
   public void borrarCampos()
   {
      for ( int cuenta = 0; cuenta < tamanio; cuenta++ )
         campos[ cuenta ].setText( "" );
   }

   // establecer valores de los campos de texto; lanzar IllegalArgumentException si
   // hay un número incorrecto de objetos String en el argumento
   public void establecerValoresCampos( String cadenas[] )
      throws IllegalArgumentException
   {
      if ( cadenas.length != tamanio )
         throw new IllegalArgumentException( "Debe haber " +
            tamanio + " objetos String en el arreglo" );

      for ( int cuenta = 0; cuenta < tamanio; cuenta++ )
         campos[ cuenta ].setText( cadenas[ cuenta ] );
   }

   // obtener arreglo de objetos String con el contenido actual de los campos de texto
   public String[] obtenerValoresCampos()
   {
      String valores[] = new String[ tamanio ];

      for ( int cuenta = 0; cuenta < tamanio; cuenta++ )
         valores[ cuenta ] = campos[ cuenta ].getText();

      return valores;
   }

} // fin de la clase IUBanco

La clase RegistroCuentas.java es una clase que representa un registro de información:

import java.io.Serializable;
public class RegistroCuentas implements Serializable
{
   private int cuenta;
   private String primerNombre;
   private String apellidoPaterno;
   private double saldo;

   // el constructor sin argumentos llama al otro constructor con valores predeterminados
   public RegistroCuentas()
   {
      this( 0, "", "", 0.0 );
   }

   // inicializar un registro
   public RegistroCuentas( int cta, String nombre, String apellido, double sald )
   {
      establecerCuenta( cta );
      establecerPrimerNombre( nombre );
      establecerApellidoPaterno( apellido );
      establecerSaldo( sald );
   }

   // establecer número de cuenta
   public void establecerCuenta( int cta )
   {
      cuenta = cta;
   }

   // obtener número de cuenta
   public int obtenerCuenta()
   {
      return cuenta;
   }

   // establecer primer nombre
   public void establecerPrimerNombre( String nombre )
   {
      primerNombre = nombre;
   }

   // obtener primer nombre
   public String obtenerPrimerNombre()
   {
      return primerNombre;
   }

   // establecer apellido paterno
   public void establecerApellidoPaterno( String apellido )
   {
      apellidoPaterno = apellido;
   }

   // obtener apellido paterno
   public String obtenerApellidoPaterno()
   {
      return apellidoPaterno;
   }

   // establecer saldo
   public void establecerSaldo( double sald )
   {
      saldo = sald;
   }

   // obtener saldo
   public double obtenerSaldo()
   {
      return saldo;
   }

} // fin de la clase RegistroCuentas

RegistroCuentasAccesoAleatorio.java que hereda de RegistroCuentas.java,y proporciona los métodos necesarios para leer o escribir al archivo:

import java.io.*;
public class RegistroCuentasAccesoAleatorio extends RegistroCuentas {

    public static final int TAMANIO = 72;

   // el constructor sin argumentos llama al otro constructor con los valores predeterminados
   public RegistroCuentasAccesoAleatorio()
   {
      this( 0, "", "", 0.0 );
   }

   // inicializar un objeto RegistroCuentasAccesoAleatorio
   public RegistroCuentasAccesoAleatorio( int cuenta, String primerNombre,
      String apellidoPaterno, double saldo )
   {
      super( cuenta, primerNombre, apellidoPaterno, saldo );
   }

   // leer un registro del objeto RandomAccecssFile especificado
   public void leer( RandomAccessFile archivo ) throws IOException
   {
      establecerCuenta( archivo.readInt() );
      establecerPrimerNombre( leerNombre( archivo ) );
      establecerApellidoPaterno( leerNombre( archivo ) );
      establecerSaldo( archivo.readDouble() );
   }

   // asegurarse que el nombre sea de la longitud apropiada
   private String leerNombre( RandomAccessFile archivo ) throws IOException
   {
      char nombre[] = new char[ 15 ], temp;

      for ( int cuenta = 0; cuenta < nombre.length; cuenta++ ) {
         temp = archivo.readChar();
         nombre[ cuenta ] = temp;
      }     

      return new String( nombre ).replace( '\0', ' ' );
   }

   // escribir un registro en el objeto RandomAccessFile especificado
   public void escribir( RandomAccessFile archivo ) throws IOException
   {
      archivo.writeInt( obtenerCuenta() );
      escribirNombre( archivo, obtenerPrimerNombre() );
      escribirNombre( archivo, obtenerApellidoPaterno() );
      archivo.writeDouble( obtenerSaldo() );
   }

   // escribir un nombre en el archivo; máximo 15 caracteres
   private void escribirNombre( RandomAccessFile archivo, String nombre )
      throws IOException
   {
      StringBuffer bufer = null;

      if ( nombre != null )
         bufer = new StringBuffer( nombre );
      else
         bufer = new StringBuffer( 15 );

      bufer.setLength( 15 );
      archivo.writeChars( bufer.toString() );
   }

} // fin de la clase RegistroCuentasAccesoAleatorio

LeerArchivoAleatorio.java que posee el método main y pone a funcionar todo:

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.text.DecimalFormat;
import javax.swing.*;
public class LeerArchivoAleatorio extends JFrame {
   private IUBanco interfazUsuario;
   private RandomAccessFile entrada;
   private JButton botonSiguiente, botonAbrir;

   private static DecimalFormat dosDigitos = new DecimalFormat( "0.00" );

   // configurar GUI
   public LeerArchivoAleatorio()
   {
      super( "Leer archivo del cliente" );

      // crear instancia de interfaz de usuario reutilizable
      interfazUsuario = new IUBanco( 4 );  // cuatro campos de texto
      getContentPane().add( interfazUsuario );

      // configurar botón hacerTarea1 genérico de IUBanco
      botonAbrir = interfazUsuario.obtenerBotonHacerTarea1();
      botonAbrir.setText( "Abrir archivo para leer..." );

      // registrar componente de escucha para llamar a archivoAbrir cuando se oprima el botón
      botonAbrir.addActionListener(

         // clase interna anónima para manejar evento de botonAbrir
         new ActionListener() {

            // permitir al usuario seleccionar el archivo a abrir
            public void actionPerformed( ActionEvent evento )
            {
               abrirArchivo();
            }

         } // fin de la clase interna anónima  

      ); // fin de la llamada a addActionListener  

      // configurar botón hacerTarea2 genérico de IUBanco
      botonSiguiente = interfazUsuario.obtenerBotonHacerTarea2();
      botonSiguiente.setText( "Siguiente" );
      botonSiguiente.setEnabled( false );

      // registrar componente de escucha para llamar a leerRegistro cuando se oprima el botón
      botonSiguiente.addActionListener(

         // clase interna anónima para manejar evento de botonSiguiente
         new ActionListener() {

            // leer un registro cuando el usuario haga clic en botonSiguiente
            public void actionPerformed( ActionEvent evento )
            {
               leerRegistro();
            }

         } // fin de la clase interna anónima

      ); // fin de la llamada a addActionListener

      // registrar componente de escucha para evento de cierre de ventana
      addWindowListener(

         // clase interna anónima para manejar evento windowClosing
         new WindowAdapter() {

            // cerrar archivo y terminar la aplicación
            public void windowClosing( WindowEvent evento )
            {
               cerrarArchivo();
            }

         } // fin de la clase interna anónima

      ); // fin de la llamada a addWindowListener

      setSize( 300, 150 );
      setVisible( true );  

   } // fin del constructor

   // permitir al usuario seleccionar el archivo a abrir
   private void abrirArchivo()
   {
      // mostrar cuadro de diálogo para que el usuario pueda seleccionar el archivo
      JFileChooser selectorArchivo = new JFileChooser();
      selectorArchivo.setFileSelectionMode( JFileChooser.FILES_ONLY );

      int resultado = selectorArchivo.showOpenDialog( this );

      // si el usuario hizo clic en el botón Cancelar del cuadro de diálogo, regresar
      if ( resultado == JFileChooser.CANCEL_OPTION )
         return;

      // obtener el archivo seleccionado
      File nombreArchivo = selectorArchivo.getSelectedFile();

      // mostrar error si el nombre de archivo es incorrecto
      if ( nombreArchivo == null || nombreArchivo.getName().equals( "" ) )
         JOptionPane.showMessageDialog( this, "Nombre de archivo incorrecto",
            "Nombre de archivo incorrecto", JOptionPane.ERROR_MESSAGE );

      else {

         // abrir el archivo
         try {
            entrada = new RandomAccessFile( nombreArchivo, "r" );
            botonSiguiente.setEnabled( true );
            botonAbrir.setEnabled( false );
         }

         // atrapar excepción que puede ocurrir al abrir el archivo
         catch ( IOException ioException ) {
            JOptionPane.showMessageDialog( this, "El archivo no existe",
               "Nombre de archivo incorrecto", JOptionPane.ERROR_MESSAGE );
         }   

      } // fin de instrucción else

   } // fin del método abrirArchivo

   // leer un registro
   private void leerRegistro()
   {
      RegistroCuentasAccesoAleatorio registro = new RegistroCuentasAccesoAleatorio();

      // leer un registro y mostrarlo
      try {

         do {
            registro.leer( entrada );
         } while ( registro.obtenerCuenta() == 0 );

         String valores[] = { String.valueOf( registro.obtenerCuenta() ),
            registro.obtenerPrimerNombre(), registro.obtenerApellidoPaterno(),
            String.valueOf( registro.obtenerSaldo() ) };
         interfazUsuario.establecerValoresCampos( valores );
      }

      // cerrar el archivo al llegar a su fin
      catch ( EOFException excepcionEOF ) {
         JOptionPane.showMessageDialog( this, "No hay más registros",
            "Se llegó al fin del archivo", JOptionPane.INFORMATION_MESSAGE );
         cerrarArchivo();
      }

      // procesar excepciones que pueden ocurrir por algún problema con el archivo
      catch ( IOException excepcionES ) {
         JOptionPane.showMessageDialog( this, "Error al leer el archivo",
            "Error", JOptionPane.ERROR_MESSAGE );

         System.exit( 1 );
      }

   } // fin del método leerRegistro
   // cerrar el archivo y terminar la aplicación
   private void cerrarArchivo()
   {
      // cerrar el archivo y salir
      try {
         if ( entrada != null )
            entrada.close();

         System.exit( 0 );
      }
      // procesar excepción que puede ocurrir al cerrar el archivo
      catch( IOException excepcionES ) {
         JOptionPane.showMessageDialog( this, "Error al cerrar el archivo",
            "Error", JOptionPane.ERROR_MESSAGE );

         System.exit( 1 );
      }

   } // fin del método cerrarArchivo
   public static void main( String args[] )
   {
      JFrame.setDefaultLookAndFeelDecorated(true);
      JDialog.setDefaultLookAndFeelDecorated(true);
      new LeerArchivoAleatorio();
   }
} // fin de la clase LeerArchivoAleatorio

Descargar código fuente

Los ejercicios utilizados en este post están basados en ejemplos del libro Cómo programar en Java de Deitel, y por lo tanto están bajo la licencia que esta editorial disponga.

23 Comentarios | deja el tuyo

23 Comentarios en “[código] Leer datos en forma secuencial, de un archivo de acceso aleatorio”

  1. libita dice:

    faltaria el JPanel

  2. juan cerron dice:

    muy buena todo la tutoria

  3. Fer dice:

    Sería bueno decir que los ejemplos los sacas del libro de Deitel

¡Déjanos tu comentario!