EOFException - como resolver?

Bom dia! Fiz um programa pra faculdade e estou tendo um problema com EOFException. sei que este ocorre quando o fim do arquivo é atingido inesperadamente, mas não sei como resolver neste caso! segue o código: (A exceção ocorre na linha após o while, readData = ds.readUTF():wink:

    JFileChooser jfc = new JFileChooser();
    int returnval = jfc.showOpenDialog(null);
    int lido = 0;
    int ultimomes = -1;
    if (returnval == JFileChooser.APPROVE_OPTION) {
        File file = jfc.getSelectedFile();
        try {
            FileInputStream fs = new FileInputStream(file);
            BufferedInputStream bs = new BufferedInputStream(fs);
            DataInputStream ds = new DataInputStream(bs);
            BufferedReader br = new BufferedReader(new InputStreamReader(fs));
            while (lido != -1) {
                String readData = ds.readUTF();
                String saidavento = Character.toString(ds.readChar()) + Character.toString(ds.readChar());
                SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
                int velocidadevento = ds.readInt();
                int pluviometro = ds.readInt();
                double temperatura = ds.readDouble();
                Date date = sdf.parse(readData);
                Calendar cal = Calendar.getInstance();
                cal.setTime(date);
                ClimaDoDia clima = new ClimaDoDia(date, saidavento, velocidadevento, pluviometro, temperatura);
                FileOutputStream primeiro = new FileOutputStream(cal.get(Calendar.YEAR) + "-" + cal.get(Calendar.MONTH) + ".dat");
                if (cal.get(Calendar.MONTH) != ultimomes) {
                    FileOutputStream proximo = new FileOutputStream(cal.get(Calendar.YEAR) + "-" + cal.get(Calendar.MONTH) + ".dat");
                    ObjectOutputStream gravar = new ObjectOutputStream(proximo);
                    gravar.writeObject(clima);
                    gravar.flush();
                    gravar.close();
                    ultimomes = cal.get(Calendar.MONTH);
                } else {
                    ObjectOutputStream gravar = new ObjectOutputStream(primeiro);
                    gravar.writeObject(clima);
                    gravar.flush();
                    gravar.close();
                    ultimomes = cal.get(Calendar.MONTH);
                }
                lido = ds.read();
            }

        } catch (FileNotFoundException ex) {
            Logger.getLogger(ClimaFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(ClimaFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParseException ex) {
            Logger.getLogger(ClimaFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
    } else {
        JOptionPane.showMessageDialog(null, "Usuário cancelou a operação!");
    }

}
    // while (lido != -1) {
    while (true) { // loop infinito
        try {

e

// lido = ds.read();
} catch(EOFException fim) {
    ds.close(); // finaliza o stream
    break; // sai do loop
}

Se ler a documentação, verá que o DataInputStream usa a exceção para avisar que terminou de ler o arquivo e não retornará -1 no read.

https://docs.oracle.com/javase/7/docs/api/java/io/DataInputStream.html#readUTF()

1 curtida

Sua sugestão resolveu aquele problema! mas agora estou com outro em mãos! :sweat_smile:

Agora parece que a exceção nunca é lançada, e o loop fica infinito!
Segue o código alterado:

    JFileChooser jfc = new JFileChooser();
    int returnval = jfc.showOpenDialog(null);
    int ultimomes = -1;
    if (returnval == JFileChooser.APPROVE_OPTION) {
        File file = jfc.getSelectedFile();
        try {
            FileInputStream fs = new FileInputStream(file);
            BufferedInputStream bs = new BufferedInputStream(fs);
            DataInputStream ds = new DataInputStream(bs);
            BufferedReader br = new BufferedReader(new InputStreamReader(fs));
            while (true) {
                try {
                    String readData = ds.readUTF();
                    String saidavento = Character.toString(ds.readChar()) + Character.toString(ds.readChar());
                    SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
                    int velocidadevento = ds.readInt();
                    int pluviometro = ds.readInt();
                    double temperatura = ds.readDouble();
                    Date date = sdf.parse(readData);
                    Calendar cal = Calendar.getInstance();
                    cal.setTime(date);
                    ClimaDoDia clima = new ClimaDoDia(date, saidavento, velocidadevento, pluviometro, temperatura);
                    FileOutputStream primeiro = new FileOutputStream(cal.get(Calendar.YEAR) + "-" + cal.get(Calendar.MONTH) + ".dat");
                    if (cal.get(Calendar.MONTH) != ultimomes) {
                        FileOutputStream proximo = new FileOutputStream(cal.get(Calendar.YEAR) + "-" + cal.get(Calendar.MONTH) + ".dat");
                        ObjectOutputStream gravar = new ObjectOutputStream(proximo);
                        gravar.writeObject(clima);
                        gravar.flush();
                        gravar.close();
                        ultimomes = cal.get(Calendar.MONTH);
                    } else {
                        ObjectOutputStream gravar = new ObjectOutputStream(primeiro);
                        gravar.writeObject(clima);
                        gravar.flush();
                        gravar.close();
                        ultimomes = cal.get(Calendar.MONTH);
                    }
                } catch (EOFException fim) {
                    ds.close();
                    break;
                }
            }
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ClimaFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(ClimaFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParseException ex) {
            Logger.getLogger(ClimaFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
    } else {
        JOptionPane.showMessageDialog(null, "Usuário cancelou a operação!");
    }

}

Pesquisei um pouco mais, tente assim:

// while (lido != -1) {
while(ds.available()>0) {

e

// lido = ds.read();
// catch removido

https://www.tutorialspoint.com/java/java_datainputstream.htm

1 curtida

Fiz as alterações, mas o loop continua infinito! :roll_eyes:
Não sei o que fazer!

    JFileChooser jfc = new JFileChooser();
    int returnval = jfc.showOpenDialog(null);
    int ultimomes = -1;
    int lido = 0;
    if (returnval == JFileChooser.APPROVE_OPTION) {
        File file = jfc.getSelectedFile();
        try {
            FileInputStream fs = new FileInputStream(file);
            BufferedInputStream bs = new BufferedInputStream(fs);
            DataInputStream ds = new DataInputStream(bs);
            BufferedReader br = new BufferedReader(new InputStreamReader(fs));
            while (lido != -1) {
                while (ds.available() > 0) {
                    String readData = ds.readUTF();
                    String saidavento = Character.toString(ds.readChar()) + Character.toString(ds.readChar());
                    SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
                    int velocidadevento = ds.readInt();
                    int pluviometro = ds.readInt();
                    double temperatura = ds.readDouble();
                    Date date = sdf.parse(readData);
                    Calendar cal = Calendar.getInstance();
                    cal.setTime(date);
                    ClimaDoDia clima = new ClimaDoDia(date, saidavento, velocidadevento, pluviometro, temperatura);
                    FileOutputStream primeiro = new FileOutputStream(cal.get(Calendar.YEAR) + "-" + cal.get(Calendar.MONTH) + ".dat");
                    if (cal.get(Calendar.MONTH) != ultimomes) {
                        FileOutputStream proximo = new FileOutputStream(cal.get(Calendar.YEAR) + "-" + cal.get(Calendar.MONTH) + ".dat");
                        ObjectOutputStream gravar = new ObjectOutputStream(proximo);
                        gravar.writeObject(clima);
                        gravar.flush();
                        gravar.close();
                        ultimomes = cal.get(Calendar.MONTH);
                    } else {
                        ObjectOutputStream gravar = new ObjectOutputStream(primeiro);
                        gravar.writeObject(clima);
                        gravar.flush();
                        gravar.close();
                        ultimomes = cal.get(Calendar.MONTH);
                    }
                }
                    lido = ds.read();
            }
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ClimaFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(ClimaFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParseException ex) {
            Logger.getLogger(ClimaFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
    } else {
        JOptionPane.showMessageDialog(null, "Usuário cancelou a operação!");
    }

}                                     

private void btRelatorioActionPerformed(java.awt.event.ActionEvent evt) {                                            
    JFileChooser jfc = new JFileChooser();
    int returnVal = jfc.showOpenDialog(null);
    if (returnVal == JFileChooser.APPROVE_OPTION) {
        FileInputStream fs = null;
        try {
            File file = jfc.getSelectedFile();
            fs = new FileInputStream(file);
            BufferedInputStream bs = new BufferedInputStream(fs);
            DataInputStream ds = new DataInputStream(bs);

        } catch (FileNotFoundException ex) {
            Logger.getLogger(ClimaFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(ClimaFrame.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                fs.close();
            } catch (IOException ex) {
                Logger.getLogger(ClimaFrame.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    } else {
        JOptionPane.showMessageDialog(null, "O usuário cancelou a operação!");
    }

remova essas linhas

1 curtida

Removi e continua infinito! poderia ser alguma particularidade do arquivo que estou tentando ler talvez?

private void btLerActionPerformed(java.awt.event.ActionEvent evt) {                                      
    JFileChooser jfc = new JFileChooser();
    int returnval = jfc.showOpenDialog(null);
    int ultimomes = -1;
    int lido = 0;
    if (returnval == JFileChooser.APPROVE_OPTION) {
        File file = jfc.getSelectedFile();
        try {
            FileInputStream fs = new FileInputStream(file);
            BufferedInputStream bs = new BufferedInputStream(fs);
            DataInputStream ds = new DataInputStream(bs);
            BufferedReader br = new BufferedReader(new InputStreamReader(fs));
            while (ds.available() > 0) {
                String readData = ds.readUTF();
                String saidavento = Character.toString(ds.readChar()) + Character.toString(ds.readChar());
                SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
                int velocidadevento = ds.readInt();
                int pluviometro = ds.readInt();
                double temperatura = ds.readDouble();
                Date date = sdf.parse(readData);
                Calendar cal = Calendar.getInstance();
                cal.setTime(date);
                ClimaDoDia clima = new ClimaDoDia(date, saidavento, velocidadevento, pluviometro, temperatura);
                FileOutputStream primeiro = new FileOutputStream(cal.get(Calendar.YEAR) + "-" + cal.get(Calendar.MONTH) + ".dat");
                if (cal.get(Calendar.MONTH) != ultimomes) {
                    FileOutputStream proximo = new FileOutputStream(cal.get(Calendar.YEAR) + "-" + cal.get(Calendar.MONTH) + ".dat");
                    ObjectOutputStream gravar = new ObjectOutputStream(proximo);
                    gravar.writeObject(clima);
                    gravar.flush();
                    gravar.close();
                    ultimomes = cal.get(Calendar.MONTH);
                } else {
                    ObjectOutputStream gravar = new ObjectOutputStream(primeiro);
                    gravar.writeObject(clima);
                    gravar.flush();
                    gravar.close();
                    ultimomes = cal.get(Calendar.MONTH);
                }
            }
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ClimaFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(ClimaFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParseException ex) {
            Logger.getLogger(ClimaFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
    } else {
        JOptionPane.showMessageDialog(null, "Usuário cancelou a operação!");
    }

}

Poderia verificar se o ds está mudando?

while (ds.available() > 0) {
  System.out.println("ds.available() : "+ds.available());
  String readData = ds.readUTF();
  System.out.println("readData : "+readData);
1 curtida

Esta é a saída! porém logo após ocorre uma EOFException!
ds.available() : 459
readData : 4/1/2018
ds.available() : 449
readData :
ds.available() : 369
readData : 7/1/2018
ds.available() : 359
@1ffffff8/1/2018

O arquivo que estou tentando ler tem esta ordem de tipos: String, String, Int, Int, Double e depois repete!

Provavelmente está lendo errado, para cada ds.read* crie um System.out.println para identificar o que está errado. Não tenho como verificar aqui.

1 curtida

Mas no código está lendo
String char char int double

1 curtida

Aparentemente está lendo tudo corretamente! São dados de diversos dias, por isso são tantos.

Saída:
ds.available() : 459
readData : 4/1/2018
Direção do vento (char + char): NE
Velocidade do vento: 20
Pluviometro: 0
Temperatura: 27.0
ds.available() : 429
readData : 5/1/2018
Direção do vento (char + char): SE
Velocidade do vento: 58
Pluviometro: 14
Temperatura: 25.2
ds.available() : 399
readData : 6/1/2018
Direção do vento (char + char): E
Velocidade do vento: 65
Pluviometro: 5
Temperatura: 18.2
ds.available() : 369
readData : 7/1/2018
Direção do vento (char + char): SW
Velocidade do vento: 50
Pluviometro: 13
Temperatura: 17.4
ds.available() : 339
readData : 8/1/2018
Direção do vento (char + char): SE
Velocidade do vento: 17
Pluviometro: 6
Temperatura: 23.0
ds.available() : 309
readData : 9/1/2018
Direção do vento (char + char): W
Velocidade do vento: 64
Pluviometro: 0
Temperatura: 21.0
ds.available() : 279
readData : 10/1/2018
Direção do vento (char + char): E
Velocidade do vento: 27
Pluviometro: 9
Temperatura: 24.6
ds.available() : 248
readData : 11/1/2018
Direção do vento (char + char): NE
Velocidade do vento: 36
Pluviometro: 2
Temperatura: 17.7
ds.available() : 217
readData : 12/1/2018
Direção do vento (char + char): SE
Velocidade do vento: 48
Pluviometro: 18
Temperatura: 22.1
ds.available() : 186
readData : 13/1/2018
Direção do vento (char + char): W
Velocidade do vento: 65
Pluviometro: 1
Temperatura: 17.4
ds.available() : 155
readData : 14/1/2018
Direção do vento (char + char): E
Velocidade do vento: 35
Pluviometro: 4
Temperatura: 22.8
ds.available() : 124
readData : 15/1/2018
Direção do vento (char + char): SW
Velocidade do vento: 12
Pluviometro: 17
Temperatura: 23.0
ds.available() : 93
readData : 16/1/2018
Direção do vento (char + char): W
Velocidade do vento: 37
Pluviometro: 0
Temperatura: 23.6
ds.available() : 62
readData : 17/1/2018
Direção do vento (char + char): NW
Velocidade do vento: 22
Pluviometro: 4
Temperatura: 23.1
ds.available() : 31
readData : 18/1/2018
Direção do vento (char + char): E
Velocidade do vento: 14
Pluviometro: 0
Temperatura: 27.3

Onde está ocorrendo a exceção?

Se for na “String readData = ds.readUTF();” seria impossível imprimir esse resultado pois antes dessa linha tem "System.out.println("ds.available() : “+ds.available());”

Então o final seria:

ds.available() : 31
readData : 18/1/2018
Direção do vento (char + char): E
Velocidade do vento: 14
Pluviometro: 0
Temperatura: 27.3
ds.available() : ?? <-- faltou essa linha

1 curtida

A exceção ocorre justamente nessa linha!

pelo que parece o programa nunca termina de ler o arquivo, porém pelo teste que fizemos antes, ele imprime todo o conteúdo do mesmo!

ds.available() : 459
readData : 4/1/2018
Direção do vento (char + char): NE
Velocidade do vento: 20
Pluviometro: 0
Temperatura: 27.0
ds.available() : 429
readData : 5/1/2018
Direção do vento (char + char): SE
Velocidade do vento: 58
Pluviometro: 14
Temperatura: 25.2
ds.available() : 399
readData : 6/1/2018
Direção do vento (char + char): E
Velocidade do vento: 65
Pluviometro: 5
Temperatura: 18.2
ds.available() : 369
readData : 7/1/2018
Direção do vento (char + char): SW
Velocidade do vento: 50
Pluviometro: 13
Temperatura: 17.4
ds.available() : 339
readData : 8/1/2018
Direção do vento (char + char): SE
Velocidade do vento: 17
Pluviometro: 6
Temperatura: 23.0
ds.available() : 309
readData : 9/1/2018
Direção do vento (char + char): W
Velocidade do vento: 64
Pluviometro: 0
Temperatura: 21.0
ds.available() : 279
readData : 10/1/2018
Direção do vento (char + char): E
Velocidade do vento: 27
Pluviometro: 9
Temperatura: 24.6
ds.available() : 248
readData : 11/1/2018
Direção do vento (char + char): NE
Velocidade do vento: 36
Pluviometro: 2
Temperatura: 17.7
ds.available() : 217
readData : 12/1/2018
Direção do vento (char + char): SE
Velocidade do vento: 48
Pluviometro: 18
Temperatura: 22.1
ds.available() : 186
readData : 13/1/2018
Direção do vento (char + char): W
Velocidade do vento: 65
Pluviometro: 1
Temperatura: 17.4
ds.available() : 155
readData : 14/1/2018
Direção do vento (char + char): E
Velocidade do vento: 35
Pluviometro: 4
Temperatura: 22.8
ds.available() : 124
readData : 15/1/2018
Direção do vento (char + char): SW
Velocidade do vento: 12
Pluviometro: 17
Temperatura: 23.0
ds.available() : 93
readData : 16/1/2018
Direção do vento (char + char): W
Velocidade do vento: 37
Pluviometro: 0
Temperatura: 23.6
ds.available() : 62
readData : 17/1/2018
Direção do vento (char + char): NW
Velocidade do vento: 22
Pluviometro: 4
Temperatura: 23.1
ds.available() : 31
readData : 18/1/2018
Direção do vento (char + char): E
Velocidade do vento: 14
Pluviometro: 0
Temperatura: 27.3

Mas não imprime o “ds.available()” ?
Então acrescente um “catch”:

    } catch (EOFException ex) {
        // fim
    } catch (FileNotFoundException ex) {
        Logger.getLogger(ClimaFrame.class.getName()).log(Level.SEVERE, null, ex);
    } 

Isso deve sumir com a exceção, mas acho que não resolveria o problema

A exceção só ocorria com o código para teste que você sugeriu antes!

while (ds.available() > 0) {
System.out.println("ds.available() : "+ds.available());
String readData = ds.readUTF();
System.out.println("readData : "+readData);

Porém, quando fiz o código para imprimir todos os dados, não ocorre a exceção, somente fica no loop infinito!

            while (ds.available() > 0) {
                try {
                    System.out.println("ds.available() : " + ds.available());
                    String readData = ds.readUTF();
                    System.out.println("readData : " + readData);
                    System.out.println("Direção do vento (char + char): " + Character.toString(ds.readChar()) + Character.toString(ds.readChar()));
                    System.out.println("Velocidade do vento: " + ds.readInt());
                    System.out.println("Pluviometro: " + ds.readInt());
                    System.out.println("Temperatura: " + ds.readDouble());
                } catch (EOFException fim) {
                  ds.close();
                  break;
                }
            }

Para que complicar tanto, pode usar essa minha classe como base para seu projeto
Esse é um dos melhores jeito de se escrever um arquivo e ler

package com.gleisonmv.engine.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/**
 * 
 * @author Gleison Morgado Vasconcelos
 *  
 */
public class FileUtil {

	/**
	 * Read context of file
	 * @param file
	 * 
	 * */
	public static String read(File file) 
	{
		// Current char
		int c = -1;
		// Build String
		StringBuilder sb = new StringBuilder();
		try 
		{
			// Read text from file
			BufferedReader br = new BufferedReader(new FileReader(file));
			// Read
			while((c = br.read()) != -1) 
			{
				// Append char in String
				sb.append((char) c);
			} 
			// Close the inputstream of file
			br.close();
			// Return the text
			return sb.toString();	
		} 
		catch (Exception e) 
		{
			// Error on read file
			e.printStackTrace(System.err);
		}
		// File error not has content
		return null;
	}
	
	public static void write(File file, String content) 
	{
		// Create the buffered writer
		try 
		{
			// Writer of file
			BufferedWriter bw = new BufferedWriter(new FileWriter(file));
			// Write the content
			bw.write(content);
			// Flush the writer content
			bw.flush();
			// Close the writer
			bw.close();	
		} 
		catch (IOException e) 
		{
			// Error on write the file
			e.printStackTrace(System.err);
		}		
	}
}
1 curtida

Cara, agradeço de verdade por isso! mas como é um trabalho pra faculdade, eu provavelmente teria problemas com o professor caso usasse uma classe pra fazer essa leitura! Hahahahaha

mas obrigado de qualquer forma!
Por acaso você não teria nenhum palpite do que poderia estar ocasionando esse loop infinito? é só esse problema que me impede de terminar o trabalho! :persevere: