ObjectOutputStream em Java – escrever Objeto em Arquivo

Brazilian Portuguese Translation:
ObjectOutputStream em Java pode ser usado para converter um objeto em OutputStream. O processo de converter um objeto para um fluxo é chamado de serialização em Java. Uma vez que um objeto é convertido em Output Stream, ele pode ser salvo em um arquivo ou banco de dados, enviado pela rede ou usado em conexões de soquete. Portanto, podemos usar FileOutputStream para escrever o objeto em um arquivo.

ObjectOutputStream

ObjectOutputStream faz parte das classes de Java IO e seu objetivo principal é fornecer uma maneira de converter objetos Java para um fluxo. Ao criar uma instância de ObjectOutputStream, devemos fornecer o OutputStream a ser utilizado. Este OutputStream é posteriormente usado pelo ObjectOutputStream para canalizar o fluxo de objetos para o fluxo de saída subjacente, por exemplo, FileOutputStream.

Requisitos do ObjectOutputStream

O objeto que queremos serializar deve implementar a interface java.io.Serializable. Serializable é apenas uma interface de marcação e não tem nenhum método abstrato que precisamos implementar. Receberemos java.io.NotSerializableException se a classe não implementar a interface Serializable. Algo semelhante ao seguinte rastreamento de pilha de exceção.

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)

Exemplo de ObjectOutputStream Java para escrever objeto em arquivo

Vamos olhar o exemplo de ObjectOutputStream Java para escrever um objeto em arquivo. Para isso, primeiro de tudo, devemos ter uma classe com algumas propriedades. Vamos criar um objeto que iremos salvar no arquivo.

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;
	}

}

Observe que não é uma exigência ter getter/setter para todas as propriedades. Ou ter um construtor sem argumento. Como você pode ver, o objeto Employee acima não possui métodos getter/setter para a propriedade “nome”. Também não possui um construtor sem argumento. Aqui está o programa mostrando como escrever um objeto em arquivo em Java usando ObjectOutputStream.

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);
			// escrever objeto em arquivo
			oos.writeObject(emp);
			System.out.println("Done");
			// fechando recursos
			oos.close();
			fos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

Abaixo, a imagem mostra a saída do programa mencionado. Se estiver se perguntando qual é o conteúdo do arquivo EmployeeObject.ser, está um pouco confuso e algo assim:

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

ObjectOutputStream com um transient

Se não quisermos que alguma propriedade do objeto seja convertida para o fluxo, devemos usar a palavra-chave transient para isso. Por exemplo, basta alterar a propriedade de função como abaixo e ela não será salva.

private transient String role;

ObjectOutputStream e serialVersionUID

Você percebeu o serialVersionUID definido no objeto Employee? É usado pelas classes ObjectOutputStream e ObjectInputStream para operações de escrita e leitura de objetos. Embora não seja obrigatório ter este campo, você deve mantê-lo. Caso contrário, sempre que alterar sua classe sem efeito nos objetos serializados anteriores, começará a falhar. Para uma análise detalhada, vá para Serialization in Java. Se estiver se perguntando se nosso programa funcionou bem ou não, use o código abaixo para ler um objeto do arquivo salvo.

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());
//Saída será "Funcionário:: Nome=Pankaj Idade=35 Gênero=Masculino Cargo=CEO"

Isso é tudo sobre java ObjectOutputStream e como usá-lo para escrever o objeto no arquivo.

Você pode conferir mais exemplos de Java IO em nosso Repositório do GitHub.

Referência: Documentação da API

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