2

sorry to bother you, once again I need help on the Java language , more precisely on the file structured as the title .

The error in question is that after you have stored more than once , I read reports an error (of course putting in append mode) , and does so even if I do all in the main program ...

My program consists of three classes in three files:

Alluno.java:

import java.io.Serializable;

class Alunno implements Serializable {
    private String nome, cognome, data_nascita, indirizzo, residenza, telefono;

    public Alunno() {
        nome = ""; cognome = ""; data_nascita = ""; indirizzo = ""; residenza = ""; telefono = "";
    }
    public void setNome(String nome) {
        this.nome = nome;
    }
    void setCognome(String cognome) {
        this.cognome = cognome;
    }
    void setData_Nascita(String data_nascita) {
        this.data_nascita = data_nascita;
    }
    void setIndirizzo(String indirizzo) {
        this.indirizzo = indirizzo;
    }
    void setResidenza(String residenza) {
        this.residenza = residenza;
    }
    void setTelefono(String telefono) {
        this.telefono = telefono;
    }
}

File.java:

import java.io.*;

class File {
    private int dim;

    public Alunno nuovoAlunno() throws IOException {
        BufferedReader t = new BufferedReader(new InputStreamReader(System.in));
        Alunno a = new Alunno();
        System.out.println("***Inserimento nuovo alunno***");
        System.out.format("Nome: ");
        a.setNome(t.readLine());
        System.out.format("Cognome: ");
        a.setCognome(t.readLine());
        System.out.format("Data di nascita: ");
        a.setData_Nascita(t.readLine());
        System.out.format("Indirizzo: ");
        a.setIndirizzo(t.readLine());
        System.out.format("Residenza: ");
        a.setResidenza(t.readLine());
        System.out.format("Telefono: ");
        a.setTelefono(t.readLine());
        return a;
    }

    public void sciviFile(Alunno a) {
        try {
            FileOutputStream f = new FileOutputStream("istituto.dat", true);
            ObjectOutputStream fOUT = new ObjectOutputStream(f);

            fOUT.writeObject(a);

            fOUT.flush();
            fOUT.close();
        } catch (Exception e) {
            System.out.println("Eccezione scrittura: " + e.getMessage());
        }
    }

    public void leggiFile() {
        Alunno a;
        try {
            FileInputStream f = new FileInputStream("istituto.dat");
            ObjectInputStream fIN = new ObjectInputStream(f);

            while (true) {
                try {
                    a = (Alunno) fIN.readObject();
                    dim++;
                    System.out.println("Dimensione file: " + dim);
                } catch (EOFException e) {
                    break;
                }
            }
            f.close();
        } catch (Exception e) {
            System.out.println("Eccezione lettura: " + e.getMessage());
        }
    }
}

IstitutoScolastico.java:

import java.io.*;

public class IstitutoScolastico {

    public static void main(String[] args) throws IOException {
        File f = new File();

        //f.sciviFile(f.nuovoAlunno());
        f.leggiFile();
    }
}

OUTPUT: Dimensione file: 1 Eccezione lettura: invalid type code: AC


I do not read more than one object if I put in append mode, where did I go wrong? Ah, anyway sorry for the grammatical errors, but I'm Italian and I helped with google translate!

MockerTim
  • 2,475
  • 1
  • 25
  • 31
Mikess
  • 41
  • 4

1 Answers1

0

The problem is that ObjectOutputStream writes a header to the file in it's constructor.

Since you call the constructor for each Alunno you append, you write a new header to the file too. However ObjectInputStream expects only one header(at the start of the file).

If you don't want to change much in your code, you should create a new ObjectInputStream for each Alunno you read, change the code in your File class:

public void leggiFile() {
    Alunno a;
    try {
        FileInputStream f = new FileInputStream("istituto.dat");
        try {
            while (true) {
                // the header is read in the constructor
                ObjectInputStream fIN = new ObjectInputStream(f);
                a = (Alunno) fIN.readObject();
                dim++;
                System.out.println("Dimensione file: " + dim);
            }
        } catch (EOFException e) { }
        f.close();
    } catch (Exception e) {
        System.out.println("Eccezione lettura: " + e.getMessage());
    }
}

A alternative would be to skip 2(?) shorts (4(?) bytes) from the FileInputStream, but if the definition of the header should change (although this seems unlikely), you might have to change your code.

Another alternative would be to read all the Alunnos that are already in the file and then write all Alunnos (including the new one) to the File starting at the beginning of the file. But this may not be as fast as you wish.

For detailed information you can read http://docs.oracle.com/javase/7/docs/platform/serialization/spec/output.html and http://docs.oracle.com/javase/7/docs/platform/serialization/spec/input.html

One last tip: If you use Java SE 7 (or higher) consider using try-with-resources for your streams.

fabian
  • 80,457
  • 12
  • 86
  • 114