Java:Usando Objetos Serializados em Java

Ao serializar objetos em java, convertemos aquele "objeto/dado" em um conjunto de bytes que podem ser armazenados em um arquivo, para que posteriormente possamos utilizar os dados novamente como o objeto original.

Complexo!!! Mas vamos utilizar uma problema de negócio para explicar isso.

= Resolvendo o Problema de negócio =

Problema: Um Agência dos correios precisamos entregar 100 cartas rapidamente, sendo que a mesma tem 10 carteiros para executar o serviço?

Para resolvermos esse problema de distribuição criamos 3 classes;


 * Carta = Objeto a ser serializado


 * Distribuidor = Pega todas as cartas, classifica e distribui entre os carteiros.
 * Ao classificarmos as cartas, crio o objeto Carta e serializo o mesmo para ser utilizado pelo Carteiro, armazenando o objeto no respectivo diretório do carteiro.


 * Carteiro = Pega as respectivas cartas, no seu diretório e faz a entrega.
 * O Carteiro pega o arquivo com o objeto e cria novamente o objeto Carta. Fazemos um print do Objeto.

Execução
Ao executarmos a classe Distribuidor

java Distribuidor

geramos os arquivos: ls /tmp/Correios/00*/ /tmp/Correios/001/: A000.obj A001.obj  A002.obj  A003.obj  A004.obj  A005.obj  A006.obj  A007.obj  A008.obj  A009.obj  A010.obj /tmp/Correios/002/: A011.obj A012.obj  A013.obj  A014.obj  A015.obj  A016.obj  A017.obj  A018.obj  A019.obj  A020.obj ... /tmp/Correios/009/: A081.obj A082.obj  A083.obj  A084.obj  A085.obj  A086.obj  A087.obj  A088.obj  A089.obj  A090.obj java Carteiro

Ao executarmos a classe Carteiro

java Carteiro

lemos os arquivos e entregamos (print) as cartas

Entrega Carta ... carta.getCep ...001 carta.getRemetente ...Fulano de Tal 010 Destinatario ...Ciclano da Silva 010 Destinatario ...Beltrano de Oliveira 010 carta.getConteudo ...Meus amigos .... Feliz Natal ... Entrega Carta ...   carta.getCep ...001 carta.getRemetente ...Fulano de Tal Destinatario ...Ciclano da Silva Destinatario ...Beltrano de Oliveira carta.getConteudo ...Meus amigos .... Feliz Natal

Performance
No exemplo estou utilizando 100 Cartas para 1 Distribuidor e 10 Carteiros, mas este valor poderia ser 10 Milhões de Cartas ou mais. Para ter a performance que eu esperava da aplicação, executei diversas vezes a aplicação Carteiro. Exemplo:

java Carteiro 001 & java Carteiro 002 & ... java Carteiro 010 &

Dessa forma posso escalar muito a aplicação, com diversos Distribuidores e aumentar os Carteiros por Distribuidor.

= Classes =

Distribuidor.java
package net.ebasso; import java.io.FileOutputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; public class Distribuidor { private static String outputCorreioDiretorio="/tmp/Correios"; private static int cartas = 100; public static void main(String[] args) { executaExemplo02; } 	public static void executaExemplo02 { Distribuidor application = new Distribuidor; try { String sufixo = ""; int j = 1; String carteiro = String.format("%03d", j); for (int i = 1; i < cartas; i++) { sufixo = String.format("%03d", i) ; ArrayList destinatarios = new ArrayList; destinatarios.add("Ciclano da Silva " + sufixo); destinatarios.add("Beltrano de Oliveira " + sufixo); application.runOnce("A"+sufixo, carteiro,"Fulano de Tal " + sufixo, destinatarios, "Meus amigos .... Feliz Natal"); if ((i % 10) == 0) { j++; carteiro = String.format("%03d", j); } 			} 		} catch (Exception e) { e.printStackTrace; } 	}       // Executa para apenas 1 carta public static void executaExemplo01 { Distribuidor application = new Distribuidor; try { ArrayList destinatarios = new ArrayList; destinatarios.add("Ciclano da Silva"); destinatarios.add("Beltrano de Oliveira"); application.runOnce("A000","001","Fulano de Tal", destinatarios, "Meus amigos .... Feliz Natal"); } catch (Exception e) { e.printStackTrace; } 	} 	private void runOnce(String messageId, String cep, String remetente, ArrayList destinatarios, String conteudo ) throws Exception { // Criando a carta e definindo os valores Carta carta = new Carta; carta.setMessageId(messageId); carta.setCep(cep); carta.setRemetente(remetente); carta.setConteudo(conteudo); carta.setDestinatarios(destinatarios); // Armazenando o objeto serializado String ojbFilename = outputCorreioDiretorio + "/" + cep + "/" + messageId + ".obj"; FileOutputStream arquivoAGravar = new FileOutputStream(ojbFilename); ObjectOutputStream objetoAGravar = new ObjectOutputStream(arquivoAGravar); objetoAGravar.writeObject(carta); objetoAGravar.flush; objetoAGravar.close; arquivoAGravar.close; } }

Carteiro.java
package net.ebasso; import java.io.File; import java.io.FileInputStream; import java.io.ObjectInputStream; import java.util.ArrayList; import java.util.Iterator; public class Carteiro { private static String inputCorreioDiretorio="/tmp/Correios"; public static void main(String[] args) { Carteiro application = new Carteiro; try { String carteiroCep="001"; if (args.length > 0) { String carteiroCep = args[0]; } 			File folder = new File(inputCorreioDiretorio + "/" + carteiroCep); File[] listOfFiles = folder.listFiles; for (int i = 0; i < listOfFiles.length; i++) { if (listOfFiles[i].isFile) { String arquivo = listOfFiles[i].getName; application.runOnce(arquivo, carteiroCep); } 			} 		} catch (Exception e) { e.printStackTrace; } 	} 	private void runOnce(String messageId, String cep) throws Exception { String inputFilename = inputCorreioDiretorio + "/" + cep + "/" + messageId; FileInputStream arquivoALer = new FileInputStream(inputFilename); ObjectInputStream objetoALer = new ObjectInputStream(arquivoALer); // Criando a carta e definindo os valores Carta carta = (Carta) objetoALer.readObject; objetoALer.close; arquivoALer.close; System.out.println("Entrega Carta ..."); System.out.println(""); System.out.println("carta.getCep ..." + carta.getCep); System.out.println("carta.getRemetente ..." + carta.getRemetente); ArrayList destinatarios = carta.getDestinatarios; Iterator iterator = destinatarios.iterator; while (iterator.hasNext) { String destinatario = (String) iterator.next; System.out.println("Destinatario ..." + destinatario); } 		System.out.println(""); System.out.println("carta.getConteudo ..." + carta.getConteudo); } }

Carta.java
package net.ebasso; import java.io.Serializable; import java.util.ArrayList; public class Carta implements Serializable{ private static final long serialVersionUID = 3818318077429278285L; private String messageId; private String cep; private String remetente; private ArrayList destinatarios; private String conteudo; public String getMessageId { return messageId; } 	public void setMessageId( 			String messageId) { this.messageId = messageId; } 	public String getCep { return cep; } 	public void setCep( 			String cep) { this.cep = cep; } 	public String getRemetente { return remetente; }       public void setRemetente( 			String remetente) { this.remetente = remetente; } 	public String getConteudo { return conteudo; } 	public void setConteudo( 			String conteudo) { this.conteudo = conteudo; } 	public ArrayList getDestinatarios { return destinatarios; } 	public void setDestinatarios( 			ArrayList destinatarios) { this.destinatarios = destinatarios; } }