Java - 如何使 ObjectInputStream 从文件中读取所有对象
Java - How to make ObjectInputStream read all objects from file
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 时,都会创建一个 class 的新对象,将其保存到列表并保存到文件中。当我尝试在下一次执行程序时从文件中读取对象时,它只从文件中读取第一个对象,而在下一次 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)
我想知道如何读取文件中存储的所有对象并将它们添加到列表中。
谢谢,
克莱门特
ObjectOutputStream 被设计为只写入一次流。它不是为附加而设计的。最简单的解决方案是创建一个 List
并将该列表写入文件。另一种方法是创建自己的协议来包装对象输出流,尽管这可能更复杂。
简而言之,如果您想添加一个项目,您需要阅读那里的内容,将项目添加到列表和 replace/overwrite 文件。
顺便说一句,.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;
}
}
}
}
check this question
此外,您应该检查如何处理 java 中的资源,例如here.
如果您想在 .txt 文件中逐个对象保存,可以使用 JSON 解析器(例如 jackson)
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 时,都会创建一个 class 的新对象,将其保存到列表并保存到文件中。当我尝试在下一次执行程序时从文件中读取对象时,它只从文件中读取第一个对象,而在下一次 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)
我想知道如何读取文件中存储的所有对象并将它们添加到列表中。
谢谢, 克莱门特
ObjectOutputStream 被设计为只写入一次流。它不是为附加而设计的。最简单的解决方案是创建一个 List
并将该列表写入文件。另一种方法是创建自己的协议来包装对象输出流,尽管这可能更复杂。
简而言之,如果您想添加一个项目,您需要阅读那里的内容,将项目添加到列表和 replace/overwrite 文件。
顺便说一句,.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;
}
}
}
}
check this question
此外,您应该检查如何处理 java 中的资源,例如here.
如果您想在 .txt 文件中逐个对象保存,可以使用 JSON 解析器(例如 jackson)