文件结构化错误

时间:2013-12-02 17:03:45

标签: java

很抱歉打扰你,我再次需要Java语言方面的帮助,更确切地说是关于标题文件的文件。

有问题的错误是,在您多次存储后,我会报告错误报告(当然是放入追加模式),即使我在主程序中执行了所有操作,也会这样做...

我的程序由三个文件中的三个类组成:

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();
    }
}

输出: Dimensione文件:1 Eccezione lettura:无效的类型代码:AC


如果我进入追加模式,我不会读取多个对象,我哪里出错了? 啊,无论如何抱歉语法错误,但我是意大利人,我帮助谷歌翻译!

1 个答案:

答案 0 :(得分:0)

问题是ObjectOutputStream在其构造函数中将标题写入文件。

由于您为追加的每个Alunno调用构造函数,因此您也会在文件中写入新的标题。 但是ObjectInputStream只需要一个标题(在文件的开头)。

如果您不想在代码中进行太多更改,则应为您阅读的每个ObjectInputStream创建一个新的Alunno,更改File类中的代码:

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());
    }
}

另一种方法是从FileInputStream跳过2(?)短(4(?)字节),但如果标题的定义应该改变(虽然这似乎不太可能),你可能需要改变你的代码。

另一种方法是读取文件中已有的所有Alunno,然后将所有Alunno(包括新的)写入文件开头的文件。但这可能没有你想要的那么快。

有关详细信息,请参阅http://docs.oracle.com/javase/7/docs/platform/serialization/spec/output.htmlhttp://docs.oracle.com/javase/7/docs/platform/serialization/spec/input.html

最后一个提示:如果您使用Java SE 7(或更高版本),请考虑为您的流使用try-with-resources