Java中的ObjectOutputStream –将对象写入文件

时间:2020-02-23 14:37:22  来源:igfitidea点击:

Java中的ObjectOutputStream可用于将对象转换为OutputStream。
将对象转换为流的过程在Java中称为序列化。

将对象转换为输出流后,可以将其保存到文件或者数据库中,通过网络发送或者用于套接字连接。
因此,我们可以使用FileOutputStream将Object写入文件。

ObjectOutputStream

ObjectOutputStream是Java IO类的一部分,其整个目的是为我们提供一种将Java对象转换为流的方法。
创建ObjectOutputStream的实例时,我们必须提供要使用的OutputStream。
ObjectOutputStream进一步使用此OutputStream将对象流引导到基础输出流,例如FileOutputStream。

ObjectOutputStream要求

我们要序列化的对象应该实现java.io.Serializable接口。
可序列化只是一个标记接口,没有我们必须实现的任何抽象方法。
如果该类未实现Serializable接口,则将获得java.io.NotSerializableException。
异常堆栈跟踪下面的内容。

java.io.NotSerializableException: com.theitroad.files.EmployeeObject
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at com.theitroad.files.ObjectOutputStreamExample.main(ObjectOutputStreamExample.java:21)

Java ObjectOutputStream示例将对象写入文件

Le,t看一下java ObjectOutputStream示例,将一个对象写入文件。
首先,我们应该有一个带有某些属性的类。

让我们创建一个对象,将其保存到文件中。

package com.theitroad.files;

import java.io.Serializable;

public class Employee implements Serializable {

	private static final long serialVersionUID = -299482035708790407L;

	private String name;
	private String gender;
	private int age;

	private String role;
	//private transient String role;

	public Employee(String n) {
		this.name = n;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getRole() {
		return role;
	}

	public void setRole(String role) {
		this.role = role;
	}

	@Override
	public String toString() {
		return "Employee:: Name=" + this.name + " Age=" + this.age + " Gender=" + this.gender + " Role=" + this.role;
	}

}

请注意,并不需要所有属性都具有getter/setter方法。
或者拥有一个无参数的构造函数。

如您所见,上面的Employee对象没有"名称"属性的getter/setter方法。
它也没有无参数的构造函数。

这是显示如何使用ObjectOutputStream在Java中将对象写入文件的程序。

package com.theitroad.files;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class ObjectOutputStreamExample {

	public static void main(String[] args) {
		Employee emp = new Employee("hyman");

		emp.setAge(35);
		emp.setGender("Male");
		emp.setRole("CEO");
		System.out.println(emp);
		
		try {
			FileOutputStream fos = new FileOutputStream("EmployeeObject.ser");
			ObjectOutputStream oos = new ObjectOutputStream(fos);
			//write object to file
			oos.writeObject(emp);
			System.out.println("Done");
			//closing resources
			oos.close();
			fos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

下图显示了以上程序的输出。

如果您想知道" EmployeeObject.ser"文件的内容是什么,它有点乱码,如下所示。

��srcom.theitroad.files.Employee�����yyIageLgendertLjava/lang/String;Lnameq~Lroleq~xp#tMalethymantCEO

具有瞬态的ObjectOutputStream

如果我们不希望将某些对象属性转换为流,则必须使用transient关键字。
例如,只需更改如下的role属性,就不会保存它。

private transient String role;

ObjectOutputStream和serialVersionUID

您是否注意到Employee对象中定义的" serialVersionUID"? " ObjectOutputStream"和" ObjectInputStream"类将其用于写入和读取对象操作。
尽管此字段不是强制性的,但是您应该保留它。
否则,只要您更改对早期序列化对象没有影响的类,它就会开始失败。
有关详细分析,请转到Java中的序列化。

如果您想知道我们的程序是否运行良好,请使用以下代码从保存的文件中读取对象。

FileInputStream is = new FileInputStream("EmployeeObject.ser");
ObjectInputStream ois = new ObjectInputStream(is);
Employee emp = (Employee) ois.readObject();

ois.close();
is.close();
System.out.println(emp.toString());
//Output will be "Employee:: Name=hyman Age=35 Gender=Male Role=CEO"