Java 中的 ObjectOutputStream – 將對象寫入文件

ObjectOutputStream在Java中可以用來將物件轉換為OutputStream。將物件轉換為串流的過程稱為Java中的序列化。一旦物件轉換為Output Stream,就可以將其保存到文件或數據庫、通過網絡發送或在套接字連接中使用。因此,我們可以使用FileOutputStream將物件寫入文件。

ObjectOutputStream

ObjectOutputStream是Java IO類的一部分,它的整個目的是為我們提供一種將Java物件轉換為串流的方法。當我們創建ObjectOutputStream的實例時,必須提供要使用的OutputStream。這個OutputStream被ObjectOutputStream進一步用於將物件串流傳輸到底層的輸出串流,例如FileOutputStream

ObjectOutputStream的要求

我們要序列化的對象應該實現 java.io.Serializable 接口。 Serializable 只是一個標記接口,並沒有任何我們需要實現的抽象方法。如果該類沒有實現 Serializable 接口,我們將獲得 java.io.NotSerializableException。就像下面的異常堆棧跟踪一樣。

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

Java ObjectOutputStream 示例,將對象寫入文件

讓我們來看一下使用 java ObjectOutputStream 的示例,將對象寫入文件。為此,我們首先應該有一個帶有一些屬性的類。讓我們創建一個我們將保存到文件中的對象。

package com.journaldev.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 對象沒有為“name”屬性提供 getter/setter 方法。它也沒有無參數的構造方法。以下是顯示如何使用 ObjectOutputStream 在 Java 中將對象寫入文件的程序。

package com.journaldev.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("Pankaj");

		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);
			// 將對象寫入文件
			oos.writeObject(emp);
			System.out.println("Done");
			// 關閉資源
			oos.close();
			fos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

以下圖像顯示了上述程序的輸出。如果你想知道EmployeeObject.ser文件的內容,它有點亂且類似於以下內容。

��srcom.journaldev.files.Employee�����yyIageLgendertLjava/lang/String;Lnameq~Lroleq~xp#tMaletPankajtCEO

使用transient的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());
//輸出將是"Employee:: Name=Pankaj Age=35 Gender=Male Role=CEO"

這就是關於Java ObjectOutputStream以及如何使用它將對象寫入文件的全部內容。

您可以從我們的GitHub存儲庫中查看更多Java IO示例。

參考:API文檔

Source:
https://www.digitalocean.com/community/tutorials/objectoutputstream-java-write-object-file