objectinputstream在附加数据后未读取完整文件

68de4m5k  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(362)

我正在写一个小程序,在 ArrayList 把它写进文件里。
问题在于 ObjectOutputStream 我可以在文件中添加数据 FileOutputStream("",true) . 但是当我试着用 ObjectInputStream 它只读取在第一个示例中插入的数据。但数据正在被添加到文件中。
这是密码-

public void insertCustomer() throws IOException 
{       
        Customer1=new customerDetails("1", "Moeen4", "654654", "asdf", "coding", "student", "65464", "3210");
        Customer3=new customerDetails("3", "Moeen5", "888888", "asdf", "coding", "student2", "65464", "321022");
        Customer4=new customerDetails("4", "Moeen6", "654654", "asdf", "coding", "student", "65464", "7890");

        _list=new ArrayList<customerDetails>();
        _list.add(Customer1);
        _list.add(Customer3);
        _list.add(Customer4);

        customersList cl=new customersList();

        cl.WriteObjectToFile(files._customers, _list);

        ArrayList<customerDetails>li=new ArrayList<customerDetails>();
        li= (ArrayList) cl.ReadObjectFromFile(files._customers);           
        for(int i=0;i<li.size();i++)
        {   System.out.println(li.size());
            System.out.println(li.get(i).Id);
            System.out.println(li.get(i).name);
            System.out.println(li.get(i).annual_Salary);
            System.out.println(li.get(i).Company);
            System.out.println(li.get(i).dateOfBirth);
            System.out.println(li.get(i).phone_Number);
        }
    }

public void WriteObjectToFile(String filepath,Object serObj) {       
    try {

        FileOutputStream fileOut = new FileOutputStream(filepath,true);
        ObjectOutputStream objectOut = new ObjectOutputStream(fileOut);
        objectOut.writeObject(serObj);
        objectOut.close();
        System.out.println("The Object  was succesfully written to a file");

    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

public Object ReadObjectFromFile(String filepath) {      
    try {

        FileInputStream fileIn = new FileInputStream(filepath);
        ObjectInputStream objectIn = new ObjectInputStream(fileIn);

        Object obj = objectIn.readObject();
        objectIn.close();
        System.out.println("The Object has been read from the file");

        return obj;

    } catch (Exception ex) {
        ex.printStackTrace();
        return null;
    }
}
nwo49xxi

nwo49xxi1#

正如所建议的那样,代码只读取第一个对象,您需要使用一个循环从多次写入中读取所有对象。
然而-
如果您更改上述代码,即。 ReadObjectFromFile 使用循环将导致 StreamCorruptedException: invalid type code: AC . 这个 ObjectOutputStream 构造函数将序列化流头写入 OutputStream i、 e.当文件关闭并使用 new ObjectOutputStream 以及 new FileOutputStream(filepath, true) 一个新的头文件将在append点被写入,因此您将得到一个异常,因为头文件只在文件的开头出现一次
这需要处理,例如。
使用相同的 ObjectOutputStream 持续时间
覆盖 java.io.ObjectOutputStream.writeStreamHeader() 说明追加到文件的原因
改变方法和用途 List<List<Object>> 你可以把它作为一个整体来读,加,写。
循环示例将引发异常,除非 ObjectOutputStream 方法改变了

public Object ReadObjectFromFile(String filepath) {

    List<List<Object>> objects = new ArrayList<>();

    FileInputStream fileIn = new FileInputStream(filepath);
    ObjectInputStream objectIn = new ObjectInputStream(fileIn);

    try {
        while (true) {
            List<Object> obj = (List<Object>) objectIn.readObject();
            // This will throw StreamCorruptedException: invalid type code: AC
            objects.add(obj);
            System.out.println("The Object has been read from the file");                
        }
    } catch (EOFException ex) {
        // ENDS WHEN ALL READ
    } finally {
        fileIn.close();
        objectIn.close();
    }

    return objects;
}

sudo代码 List<List<Object>> 接近-

public void readAndWrite() {
    List<Object> customer = List.of(new CustomerDetails(...),
                                    new CustomerDetails(...),
                                    new CustomerDetails(...));

    List<List<Object>> objects = readFromFile("existing-customer-file.txt");

    objects.addAll(customer);

    writeObjectToFile(objects);
}
0ejtzxu1

0ejtzxu12#

真正的问题是:

FileOutputStream fileOut = new FileOutputStream(filepath, true);
  ObjectOutputStream objectOut = new ObjectOutputStream(fileOut);
  objectOut.writeObject(serObj);

不能像这样附加到现有序列化。如果尝试读取附加到预先存在(非空)文件的任何对象时出现异常。
有一个技巧/黑客允许你附加对象;请参见附加到objectoutputstream(技巧包括抑制对象流头的写入。通过重写执行此操作的方法最容易完成。)
另一种方法是保持 ObjectOutputStream 中间开口 writeObject 电话。然而,在某些用例中,这是不可能的。
请注意,这两种方法在语义上有区别。最好的解释方式是第一个人的行为就像你打电话一样 reset() 每次你写一个对象;参见javadoc。
关于您的示例,需要注意的另一点是,您的读取器代码只读取一个对象。如果要读取多个对象,需要调用 readObject 在一个循环中。只有在使用了上面的技巧/技巧来避免编写虚假的头文件时,这才有效。

相关问题