[código] Escribir en un archivo aleatorio usando Java
Luego de crear un archivo aleatorio en Java, el siguiente paso es poder escribir sobre el mismo, y al igual que en el ejemplo anterior usaremos la clase RandomAccessFile. El siguiente ejemplo veremos cómo buscar una posición exacta dentro del archivo, para escribir sobre el mismo. Para esto utilizaremos el método seek de RandomAccessFile.
Para que este ejemplo te funcione correctamente, es necesario que hayas ejecutado el anterior ejemplo.
El resultado...


El código...
La clase RegistroCuentas.java, 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
La clase RegistroCuentasAccesoAleatorio.java hereda de RegistroCuentas.java, y contiene los métodos necesarios para escribir sobre el 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
La clase IUBanco.java, que ya la hemos usado en otros ejemplos, proporciona la interfaz de usuario básica para realizar digitar los campos:
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
Finalmente la clase EscribirArchivoAleatorio.java, que contiene el método main:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
public class EscribirArchivoAleatorio extends JFrame {
private RandomAccessFile salida;
private IUBanco interfazUsuario;
private JButton botonEntrar, botonAbrir;
private static final int NUMERO_REGISTROS = 100;
// configurar GUI
public EscribirArchivoAleatorio()
{
super( "Escribir en archivo de acceso aleatorio" );
// crear instancia de la interfaz de usuario reutilizable IUBanco
interfazUsuario = new IUBanco( 4 ); // cuatro campos de texto
getContentPane().add( interfazUsuario,
BorderLayout.CENTER );
// obtener referencia al botón de tarea genérico hacerTarea1 en IUBanco
botonAbrir = interfazUsuario.obtenerBotonHacerTarea1();
botonAbrir.setText( "Abrir..." );
// registrar componente de escucha para llamar a abrirArchivo 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
// registrar componente de escucha de ventana para el evento de cierre de ventana
addWindowListener(
// clase interna anónima para manejar evento windowClosing
new WindowAdapter() {
// agregar registro en la GUI, después cerrar el archivo
public void windowClosing( WindowEvent evento )
{
if ( salida != null )
agregarRegistro();
cerrarArchivo();
}
} // fin de la clase interna anónima
); // fin de la llamada a addWindowListener
// obtener referencia al botón de tarea genérico hacerTarea2 en IUBanco
botonEntrar = interfazUsuario.obtenerBotonHacerTarea2();
botonEntrar.setText( "Introducir" );
botonEntrar.setEnabled( false );
// registrar componente de escucha para llamar a agregarRegistro cuando se oprima el botón
botonEntrar.addActionListener(
// clase interna anónima para manejar evento de botonEntrar
new ActionListener() {
// agregar registro al archivo
public void actionPerformed( ActionEvent evento )
{
agregarRegistro();
}
} // fin de la clase interna anónima
); // fin de la llamada a addActionListener
setSize( 300, 150 );
setVisible( true );
}
// 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 {
salida = new RandomAccessFile( nombreArchivo, "rw" );
botonEntrar.setEnabled( true );
botonAbrir.setEnabled( false );
}
// procesar excepción que puede ocurrir al abrir el archivo
catch ( IOException excepcionES ) {
JOptionPane.showMessageDialog( this, "El archivo no existe",
"Nombre de archivo incorrecto", JOptionPane.ERROR_MESSAGE );
}
} // fin de instrucción else
} // fin del método abrirArchivo
// cerrar el archivo y terminar la aplicación
private void cerrarArchivo()
{
// cerrar el archivo y salir
try {
if ( salida != null )
salida.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
// agregar un registro al archivo
private void agregarRegistro()
{
String campos[] = interfazUsuario.obtenerValoresCampos();
// asegurarse que el campo cuenta tenga un valor
if ( ! campos[ IUBanco.CUENTA ].equals( "" ) ) {
// escribir valores en el archivo
try {
int numeroCuenta = Integer.parseInt( campos[ IUBanco.CUENTA ] );
if ( numeroCuenta > 0 && numeroCuenta <= NUMERO_REGISTROS ) {
RegistroCuentasAccesoAleatorio registro =
new RegistroCuentasAccesoAleatorio();
registro.establecerCuenta( numeroCuenta );
registro.establecerPrimerNombre( campos[ IUBanco.PRIMERNOMBRE ] );
registro.establecerApellidoPaterno( campos[ IUBanco.APELLIDO ] );
registro.establecerSaldo( Double.parseDouble(
campos[ IUBanco.SALDO ] ) );
salida.seek( ( numeroCuenta - 1 ) *
RegistroCuentasAccesoAleatorio.TAMANIO );
registro.escribir( salida );
}
else
{
JOptionPane.showMessageDialog( this,
"El número de cuenta debe ser entre 0 y 100",
"Número de cuenta incorrecto", JOptionPane.ERROR_MESSAGE );
}
interfazUsuario.borrarCampos(); // borrar el contenido de los campos de texto
} // fin del bloque try
// procesar formato incorrecto de número de cuenta o saldo
catch ( NumberFormatException excepcionFormato ) {
JOptionPane.showMessageDialog( this,
"Número de cuenta o saldo incorrectos",
"Formato de número incorrecto", JOptionPane.ERROR_MESSAGE );
}
// procesar excepciones que pueden ocurrir al escribir en el archivo
catch ( IOException excepcionES ) {
JOptionPane.showMessageDialog( this,
"Error al escribir en el archivo", "Excepción de ES",
JOptionPane.ERROR_MESSAGE );
cerrarArchivo();
}
} // fin de instrucción if
} // fin del método agregarRegistro
public static void main( String args[] )
{
JFrame.setDefaultLookAndFeelDecorated(true);
JDialog.setDefaultLookAndFeelDecorated(true);
new EscribirArchivoAleatorio();
}
} // fin de la clase EscribirArchivoAleatorio








