Java-如何使ObjectInputStream读取文件中的所有对象

时间:2018-10-13 08:58:16

标签: java fileinputstream fileoutputstream objectoutputstream

import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Scanner;
public class FileDemo implements Serializable
{
    static ArrayList<FileDemo> list=new ArrayList<FileDemo>();

    public static void main(String[] args) throws Exception 
    {
        File file=new File("log.txt");
        if(!file.createNewFile() && file.length()!=0)
        {
            FileInputStream fis=new FileInputStream("log.txt");
            ObjectInputStream ois=new ObjectInputStream(fis);
            while(true)
            {
                try{
                    list.add((FileDemo)ois.readObject());                   
                }
                catch(EOFException e) {
                    break;
                }
                catch(Exception e) {
                    e.printStackTrace();
                    break;
                }
            }
            ois.close();
            fis.close();
        }
        Scanner scn=new Scanner(System.in);
        int x=0;
        while(x!=3)
        {
            System.out.println("MENU");
            System.out.println("Enter 1 to add new object to file");
            System.out.println("Enter 2 to display list size");
            System.out.println("Enter 3 to exit");
            System.out.print("Enter your choice: ");
            x=scn.nextInt();
            if(x==1)
            {
                FileDemo filedemo=new FileDemo();
                list.add(filedemo);
                FileOutputStream fos=new FileOutputStream("log.txt",true);
                ObjectOutputStream oos=new ObjectOutputStream(fos);
                oos.writeObject(filedemo);
                oos.close();
                fos.close();
                System.out.println("Object Created");
            }
            else if(x==2)
                {
                    System.out.println(list.size());
                }
            else if(x==3)
                break;
            else
                System.out.println("Invaild choice");
        }
    }
}

嗨, 在此程序中,每当用户在菜单中输入选项1时,都会创建该类的新对象,将其保存到列表中并保存到文件中。当我尝试在程序的下一次执行时从文件中读取对象时,它仅从文件中读取第一个对象,并在下一次readObject()调用时引发如下异常:

java.io.StreamCorruptedException: invalid type code: AC
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at FileDemo.main(FileDemo.java:25)

我想知道如何读取文件中存储的所有对象并将它们添加到列表中。

谢谢, 克莱门特(Clement)

2 个答案:

答案 0 :(得分:1)

ObjectOutputStream设计为仅写入一次流。它不是为追加而设计的。最简单的解决方案是创建一个List并将该列表写入文件。一种替代方法是创建自己的协议来包装对象输出流,尽管这可能会更复杂。

简而言之,如果要添加项目,则需要阅读其中的内容,然后将该项目添加到列表中,然后替换/覆盖文件。

顺便说一句,.txt文件应表示文本文件,但是对象流是二进制文件,因此您应该使用其他扩展名。

您可以这样编写,以便在处理用户输入的代码和存储用户数据的数据结构之间明确区分

import java.io.*;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;

public class FileDemo implements Serializable {
    static class FileList implements Serializable {
        List<FileData> list = new ArrayList<>();
    }

    static class FileData implements Serializable { }

    public static void main(String[] args) throws IOException {
        File file = new File("log.data");
        FileList list = new FileList();
        if (file.exists()) {
            try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
                list = (FileList) ois.readObject();
            }
        }
        Scanner scn = new Scanner(System.in);
        while (true) {
            System.out.print("MENU\n" +
                    "Enter 1 to add new object to file\n" +
                    "Enter 2 to display list size\n" +
                    "Enter 3 to exit\n" +
                    "Enter your choice: ");
            int option = scn.nextInt();
            switch (option) {
                case 1:
                    list.list.add(new FileData());
                    File tmp = new File("log.data.tmp");
                    try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(tmp))) {
                        oos.writeObject(list);
                    }
                    Files.move(tmp.toPath(), file.toPath(), REPLACE_EXISTING);
                    System.out.println("Object Added");
                    break;
                case 2:
                    System.out.println(list.list.size());
                    break;
                case 3:
                    return;
                default:
                    System.out.println("Invalid choice");
                    break;
            }
        }
    }
}

答案 1 :(得分:0)

check this question

此外,您应该检查如何处理Java中的资源,例如here

如果要将对象逐个保存到.txt文件中,则可以使用JSON解析器(例如jackson