Leer registros de archivo

Para practicar los conceptos de lectura y escritura de archivos he realizado un formulario con dos botones para escribir y leer registros desde un archivo. Mi problema es que al tratar de leer los registros que introduzco por la misma aplicación me da una excepción NoSuchElementException. Mi código para leer el archivo es el siguiente:

private void leerRegistro()
{
//objeto que se va a leer en el archivo
Personas p = new Personas();
//lee los registros
try
{
lectura = new Scanner(new File("clientes.txt"));
//recibe los valores del archivo
while(lectura.hasNext())
{
p.establecerCuenta(lectura.nextInt());
p.establecerNombre(lectura.next());
p.establecerApellido(lectura.next());
p.establecerSaldo(lectura.nextDouble());
//si el saldo es el elegido lo muestra
if(debeMostrar(p.obtenerSaldo()))
jTextArea1.setText(Integer.toString(p.obtenerCuenta())+ "\t" + p.obtenerNombre() + "\t" + p.obtenerApellido()+ "\t"+ Double.toString(p.obtenerSaldo())+ "\r\n");
}
}
catch(NoSuchElementException such)
{
JOptionPane.showMessageDialog(null, "El archivo no está bien formado");
System.exit(1);
/}
catch(IllegalStateException state)
{
JOptionPane.showMessageDialog(null, "Error al leer el archivo");
System.exit(1);
}
catch(FileNotFoundException notFound)
{
JOptionPane.showMessageDialog(null, "No se puede encontrar el archivo");
System.exit(1);
}
finally
{
if(lectura != null)
lectura.close();
}
}//fin del método leer registro

Lo mas raro es que si copio y pego un archivo en el directorio ya con datos (y borro el que cargue con la aplicación), me lo lee bien pero si cargo desde la aplicación no me lo lee. Por mas que me carga sin problemas y no me da ninguno error en la carga de datos.

No entiendo porque me pasara esto.

1 respuesta

Respuesta
1

Lo que me cuentas es muy raro. En principio, tanto el archivo como la función de lectura parecen estar bien, ya que con otro archivo que es una copia del que creas funciona. Quizás el problema este con la función de escritura que no termina de cerrar ese archivo.

Mándamela y le echo un vistazo

Hola experto. gracias por la respuesta aquí adjunto el método escribirRegistro que utilizo para cargar datos en el archivo:

public void escribirArchivo()
{
Personas r = new Personas();
try
{
//inicializamos a FileWriter con dos argumentos para escribir muchos registros,
//lo hacemos con File y no true escribe solamente el ultimo registro
FileWriter fr = new FileWriter(f,true);
r.establecerCuenta(Integer.parseInt(jTextField1.getText()));
r.establecerNombre(jTextField2.getText());
r.establecerApellido(jTextField3.getText());
r.establecerSaldo(Double.parseDouble(jTextField4.getText()));
if(r.obtenerCuenta() > 0)
{
//escribe archivo
fr.write(r.obtenerCuenta() + "\t" + r.obtenerNombre()+"\t " + r.obtenerApellido() + " \t" + r.obtenerSaldo() + "\r\n");
// fr.write("\r\n");
JOptionPane.showMessageDialog(null, "Cliente cargado con éxito", "Carga exitosa", JOptionPane.INFORMATION_MESSAGE);
}
else
{
JOptionPane.showMessageDialog(null, "El número de cuenta debe ser mayor que cero");
}
fr.close();
}

¿Por qué no pones la linea fr.close dentro de un bloque finally, en lugar de hacerlo dentro del bloque try? Ademas, defines un bloque try pero no tratas las excepciones con un bloque catch.

Es lo único que podría hacer que no se cerrara el archivo. Ya me contaras

Hola experto, gracias por la ayuda sabes que trate de cerrar el fr desde un finally y no me deja, se como si perdiera el alcance el objeto. Aquí esta el código:

public void escribirArchivo()
{
Personas r = new Personas();
try
{
//inicializamos a FileWriter con dos argumentos para escribir muchos registros,
//lo hacemos con File y no true escribe solamente el ultimo registro
FileWriter fr = new FileWriter(f,true);
r.establecerCuenta(Integer.parseInt(jTextField1.getText()));
r.establecerNombre(jTextField2.getText());
r.establecerApellido(jTextField3.getText());
r.establecerSaldo(Double.parseDouble(jTextField4.getText()));
if(r.obtenerCuenta() > 0)
{
//escribe archivo
fr.write(r.obtenerCuenta() + "\t" + r.obtenerNombre()+"\t " + r.obtenerApellido() + " \t" + r.obtenerSaldo() + "\r\n");
// fr.write("\r\n");
JOptionPane.showMessageDialog(null, "Cliente cargado con éxito", "Carga exitosa", JOptionPane.INFORMATION_MESSAGE);
}
else
{
JOptionPane.showMessageDialog(null, "El número de cuenta debe ser mayor que cero");
}
fr.close();
}
catch (Exception ex)
{
JOptionPane.showMessageDialog(null, ex.getStackTrace());
}
finally
{

//aquí había puesto el fr.close() pero no me daba los métodos del objeto para poder cerrarlo. Probé sin la instrucción para que lo cierre implícitamente pero esigue sin poder leerlo. Aunque genera el archivo sin problemas
}
}//fin del método escribirArchivo

Gracias por la ayuda experto, la verdad es que pruebo y pruebo y no doy con la lectura!!

El problema que tienes es que declaras el FileWriter dentro del bloque try y por eso no te deja utilizarlo fuera de dicho bloque try. Decláralo antes, de esta forma

FileWriter fr;

try {

fr = new FileWriter (f, true);

...

Así podrás utilizarlo en el bloque finally para poder cerrar el archivo.

Hola experto gracias por la ayuda. Opte por cambiar el método de escribir en el archivo es el siguiente:

public void escribirArchivo()
{
try
{
PrintWriter salida = new PrintWriter(new BufferedWriter(new FileWriter("clientes.txt",true)));
l.establecerCuenta(Integer.parseInt(jTextField1.getText()));
l.establecerNombre(jTextField2.getText());
l.establecerApellido(jTextField3.getText());
l.establecerSaldo(Double.parseDouble(jTextField4.getText()));
salida.println(l.obtenerCuenta()+ "\t" + l.obtenerNombre() + "\t" + l.obtenerApellido() + "\t" + l.obtenerSaldo());
salida.close();
JOptionPane.showMessageDialog(null, "Cliente cargado al archivo");
}
catch(Exception e)
{
JOptionPane.showMessageDialog(null, e.getStackTrace());
}
}//fin de escribir archivo

Y modifique el método de lectura de archivo:

private void leerRegistro() throws IOException
{
//objeto que se va a leer en el archivo
Personas p = new Personas();
String es = new String();
//lee los registros
try
{
lectura = new Scanner(new File("clientes.txt"));
//recibe los valores del archivo
while(lectura.hasNext())
{
p.establecerCuenta(lectura.nextInt());
p.establecerNombre(lectura.next());
p.establecerApellido(lectura.next());
p.establecerSaldo(lectura.nextDouble());
//si el saldo es el elgido lo muestra
if(debeMostrar(p.obtenerSaldo()))
{
es = es + Integer.toString(p.obtenerCuenta())+ "\t" + p.obtenerNombre() + "\t" + p.obtenerApellido()+ "\t"+ Double.toString(p.obtenerSaldo()) + "\n";
jTextArea1.setText(es);
}
}
}// fin de lectura

Carga perfecto los datos en el archivo pero al leerlo me da un Inputmismatch en la línea:

p.establecerSaldo(lectura.nextDouble());

Como si le hubiera dado un valor que no sea double.

Cuando mi archivo de texto tiene:

1 Juan Zeballos 800.50

No entiendo porque el método nextDouble me toma el saldo como si fuera de otro tipo.

Desde ya gracias sigo probando y volviéndome loka!!

Después de tanto leer mi código mi error era que escribía con parseDouble con punto en el archivo y no con coma. Lo solucione con parseDouble en la lectura:

parseDouble(lectura.nextDouble)

Para que me lea como me escribía, es decir el punto del saldo.

Gracias!!!!

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas