java—从一个文件中读取多个对象,就像它们在一个数组中一样

java—从一个文件中读取多个对象,就像它们在一个数组中一样,java,object,Java,Object,我想问一下社区,你对以下情况有何看法。任务是将对象写入文件。这可以通过向文件中写入对象列表来实现,我可以稍后读取这些对象,这样我就可以再次拥有我的对象。在这里,我实际上只将一个对象写入文件,即列表(可能包含更多对象) 但是,任务是将单独的对象写入该文件,该方法从列表接收该文件。对象可以是任何东西。(当然,它们必须是可序列化的) 所以我做了: public class TaskStream { public static void saveObjects(ArrayList<Obje

我想问一下社区,你对以下情况有何看法。任务是将对象写入文件。这可以通过向文件中写入对象列表来实现,我可以稍后读取这些对象,这样我就可以再次拥有我的对象。在这里,我实际上只将一个对象写入文件,即列表(可能包含更多对象)

但是,任务是将单独的对象写入该文件,该方法从列表接收该文件。对象可以是任何东西。(当然,它们必须是可序列化的)

所以我做了:

public class TaskStream {
    public static void saveObjects(ArrayList<Object> al) {
        try {
            FileOutputStream fos = new FileOutputStream("outputFile", true);
            try {
                ObjectOutputStream oos = new ObjectOutputStream(fos);
                for (Object o : al){
                    try {
                        oos.writeObject(o);
                        System.out.println("saved");
                    } catch (NotSerializableException e) {
                        System.out.println("An object was not serializable, it has not been saved.");
                        e.printStackTrace();
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }
怎么可能呢?我开始使用ObjectInputStream的readObject方法,但它似乎会导致很多错误

你知道吗?或者这样一项任务的最佳实践是什么


谢谢

我试过你的主意。具体实施:

public static ArrayList<Object> readObjects(){
    ArrayList<Object> al = new ArrayList<Object>();
    boolean cont = true;
        try {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("outputFile"));
            while(cont){
                  Object obj=null;
                try {
                    obj = ois.readObject();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
                  if(obj != null)
                     al.add(obj);
                  else
                     cont = false;
               }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

 return al;
}    

我没有改变任何东西,我再次运行程序。结果:

将成功打印列表中的两个对象。 但我收到的是:

java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2598)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1318)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)    
java.io.StreamCorruptedException: invalid type code: AC
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1377)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)    
从现在起,任何重新运行都会带来相同的结果

如果我从一开始就再次重复整个过程(从删除outputFile开始),一切都会完全一样(如预期的那样)


你有办法解决它吗?非常感谢你的帮助

您需要使用FileInputStream和ObjectInputStream

FileInputStream fis = new FileInputStream("outputFile");
ArrayList<Object> objectsList = new ArrayList<>();
boolean cont = true;
while (cont) {
  try (ObjectInputStream input = new ObjectInputStream(fis)) {
    Object obj = input.readObject();
    if (obj != null) {
      objectsList.add(obj);
    } else {
      cont = false;
    }
  } catch (Exception e) {
    // System.out.println(e.printStackTrace());
  }
}
FileInputStream fis=新的FileInputStream(“outputFile”);
ArrayList objectsList=新的ArrayList();
布尔控制=真;
while(续){
try(ObjectInputStream输入=新ObjectInputStream(fis)){
Object obj=input.readObject();
如果(obj!=null){
objectsList.add(obj);
}否则{
cont=假;
}
}捕获(例外e){
//System.out.println(e.printStackTrace());
}
}

我们已经使用FileInputStream类方法“available”方法来检查给定流是否有数据或字节要读取。如果数据不存在,则此方法将返回0

public static ArrayList<Object> getObjects(){

    ArrayList<Object> objects = new ArrayList<Object>(); 
    FileInputStream fis = new FileInputStream("outputFile");
    ObjectInputStream ois = new ObjectInputStream(fis);

    Object obj =null;

    boolean isExist = true;

    while(isExist){
        if(fis.available() != 0){
         obj = (A) ois.readObject();    
         objects.add(obj);
        }
        else{
        isExist =false;
        }
    }
    return objects;     
}
publicstaticarraylistgetobjects(){
ArrayList对象=新的ArrayList();
FileInputStream fis=新的FileInputStream(“outputFile”);
ObjectInputStream ois=新ObjectInputStream(fis);
objectobj=null;
布尔值isExist=true;
while(我存在){
如果(可用财务信息()!=0){
obj=(A)ois.readObject();
对象。添加(obj);
}
否则{
isExist=假;
}
}
归还物品;
}

我们可以将所有对象添加到列表中,然后序列化列表。同样,我们可以对列表进行反序列化,并在列表上进行迭代以获得我们正在寻找的对象。它需要使用以下类别。 文件输出流 文件输入流类 ObjectInputStream ObjectOutputStream

import java.io.Serializable;
import java.util.List;
import java.util.ArrayList;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;

    public class MultiObjectSerialization {
        static String file = "helloFruits.txt";
        static ObjectOutputStream os;
        static ObjectInputStream is;

        public static void main(String[] args) throws IOException,
                ClassNotFoundException {
            Apples a = new Apples(1, "apple");
            Mango m = new Mango(2, "Mango");

            List<Object> fruits = new ArrayList<>();
            fruits.add(a);
            fruits.add(m);
            writeToFile(fruits);
            readFile();

        }

        public static void writeToFile(List<Object> fruits) throws IOException {
            os = new ObjectOutputStream(new FileOutputStream(file));
            os.writeObject(fruits);
            os.close();

        }

        public static void readFile() throws ClassNotFoundException, IOException {
            is = new ObjectInputStream(new FileInputStream(file));
            List<Object> input = (List<Object>) is.readObject();
            List<Object> checkList = new ArrayList<>();
            // this will contain the list of the objects
            for (Object l : input) {
                checkList.add(l.getClass().getSimpleName());
                if (l instanceof Apples) {
                    Apples app = (Apples) l;
                    System.out.println(app.id);
                    System.out.println(app.name);
                }
                if (l instanceof Mango) {
                    Mango app = (Mango) l;
                    System.out.println(app.id);
                    System.out.println(app.name);
                }
            }
            System.out.println(checkList);

            is.close();
        }
    }

    class Apples implements Serializable {
        private static final long serialVersionUID = 1L;
        int id;
        String name;

        public Apples(int id, String name) {
            this.id = id;
            this.name = name;
        }
    }

    class Mango implements Serializable {
        private static final long serialVersionUID = 1L;
        int id;
        String name;

        public Mango(int id, String name) {
            this.id = id;
            this.name = name;
        }
    }


  The Output is ::
    1
    apple
    2
    Mango
    [Apples, Mango]
import java.io.Serializable;
导入java.util.List;
导入java.util.ArrayList;
导入java.io.FileOutputStream;
导入java.io.FileInputStream;
导入java.io.IOException;
导入java.io.ObjectOutputStream;
导入java.io.ObjectInputStream;
公共类多对象序列化{
静态字符串文件=“helloFruits.txt”;
静态对象输出流;
静态ObjectInputStream是;
公共静态void main(字符串[]args)引发IOException,
ClassNotFoundException{
苹果a=新苹果(1,“苹果”);
芒果m=新芒果(2,“芒果”);
列表结果=新的ArrayList();
加入(a);
添加(m);
书面文件(水果);
readFile();
}
公共静态void writeToFile(列表结果)引发IOException{
os=新对象输出流(新文件输出流(文件));
os.writeObject(水果);
os.close();
}
public static void readFile()引发ClassNotFoundException、IOException{
is=新对象输入流(新文件输入流(文件));
列表输入=(列表)为.readObject();
列表检查表=新的ArrayList();
//这将包含对象列表
for(对象l:输入){
添加(l.getClass().getSimpleName());
if(苹果的l实例){
苹果app=(苹果)l;
System.out.println(应用程序id);
System.out.println(app.name);
}
if(芒果的l实例){
芒果app=(芒果)l;
System.out.println(应用程序id);
System.out.println(app.name);
}
}
系统输出打印LN(检查表);
is.close();
}
}
类实现可序列化{
私有静态最终长serialVersionUID=1L;
int-id;
字符串名;
公共苹果(int-id,字符串名){
this.id=id;
this.name=名称;
}
}
类Mango实现可序列化{
私有静态最终长serialVersionUID=1L;
int-id;
字符串名;
公共Mango(int-id,字符串名){
this.id=id;
this.name=名称;
}
}
输出为:
1.
苹果
2.
芒果
[苹果,芒果]

我知道这个话题很老,但我想我知道解决这个问题的方法。 你得到的理由是什么

`'invalid type code: AC'`
因为在您编写一个对象并尝试读取它之后,ObjectInputStream正在尝试读取您的ObjectOutputStream编写的信息。一般来说,序列化就是这样工作的。 代码中的问题是,正在创建一个新的ObjectInputStream,并尝试从旧的ObjectOutputStream读回,但它发现它们没有相同的串行代码,因此出现此错误

我在不久前发布的另一个主题中找到了一个解决方案,请检查此处:

他所做的是覆盖streamWriter,后者“欺骗”ObjectInputStream,使其相信自己可以阅读
`'invalid type code: AC'`
import java.io.*;
import java.util.*;
class ObjectReadWrite implements Serializable, Comparable <ObjectReadWrite>
{
    int no;
    String name;
    ObjectReadWrite(int i,String s)
    {
        this.no=i;
        this.name=s;
    }
    public String toString()
    {
        return "TP Data : "+this.no+":"+this.name;
    }
    public int compareTo(ObjectReadWrite a1)
    {
        return this.name.compareTo(a1.name);
    }
    public static void main(String args[]) throws Exception
    {
        TreeSet<ObjectReadWrite> aw = new TreeSet<ObjectReadWrite>();
        aw.add(new ObjectReadWrite(1,"ABC"));
        aw.add(new ObjectReadWrite(2,"DDF"));
        aw.add(new ObjectReadWrite(3,"DAF"));
        aw.add(new ObjectReadWrite(4,"DCF"));

        //Writing Objects From TreeSet
        ObjectOutputStream os=new ObjectOutputStream(
                    new FileOutputStream(
                    new File("Test.dat")));
        os.writeObject(aw);
        os.close();



        //Reading Objects into TreeSet
        TreeSet ar = new TreeSet();
        ObjectInputStream is=new ObjectInputStream(
                    new FileInputStream(
                    new File("Test.dat")));

        ar=(TreeSet)is.readObject();
        is.close();


        Iterator ir = ar.iterator();
        while(ir.hasNext())
        {
            System.out.println((ObjectReadWrite)ir.next());
        }

    }
}
try {
    obj = ois.readObject();
} catch (EOFException e) {
    break;
}
FileInputStream fileStream = new FileInputStream("file.txt");
        // Creates an ObjectInputStream
ObjectInputStream input = new ObjectInputStream(fileStream);
        // Reads the objects
   while (fileStream.available() != 0) {
      Object human = (Human) input.readObject();
       if (human != null)
        System.out.println(human);
}
public static class IOMannager {
    
    private static List<Produto> lista_produtos = new ArrayList<Produto>();
        
    public static void ler() {
            
        ObjectInputStream in = null;
        try{
            in = new ObjectInputStream(new FileInputStream("produtos.txt"));
            Object obj = in.readObject();
            in.close();
            lista_produtos = (ArrayList<Produto>) obj;
        }
        //catches goes here....
    }
}
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
listeSolutions.clear();
Solution s;
while (true) {
try {
s = (Solution) ois.readObject();

listeSolutions.add(s);
} catch (Exception e) {
break; }
}
ois.close();
} catch (Exception e) {
e.printStackTrace(); 
}