【问题标题】:Java - How to make ObjectInputStream read all objects from fileJava - 如何让 ObjectInputStream 从文件中读取所有对象
【发布时间】:2018-10-13 08:58:15
【问题描述】:
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)

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

谢谢你, 克莱门特

【问题讨论】:

    标签: java fileinputstream fileoutputstream objectoutputstream


    【解决方案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;
                }
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      check this question

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

      如果你想在.txt文件中逐个对象保存,你可以使用JSON解析器(例如jackson

      【讨论】:

        猜你喜欢
        • 2014-05-30
        • 1970-01-01
        • 2013-07-07
        • 1970-01-01
        • 1970-01-01
        • 2012-07-31
        • 1970-01-01
        • 2019-12-12
        • 1970-01-01
        相关资源
        最近更新 更多