Páginas

terça-feira, 8 de julho de 2014

Redirecionando System.out e System.err para Arquivos

As chamadas System.out.print e System.err.print devem ser os recursos mais comumente utilizados em Java, e frequentemente utilizado nos exemplos deste blog, mas este tipo de recurso deve ser utilizado com objetivo limitado principalmente em testes ou debugs rápidos, sendo preferível o uso de uma API de log para o registro de mensagens importantes na avaliação da saúde de uma aplicação. Mas, você gostaria de continuar utilizando as chamadas System por uma questão de apego ou qualquer outro motivo, então veremos nesta postagem como redirecionar a saída destas chamadas para um arquivo.

Direto para o código

Vamos direto para o código e depois algumas considerações:
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;

public class SysErrOutRedirect {
 public static void main(final String[] args) {

  FileOutputStream efos = null;
  try {
   efos = new FileOutputStream("err.txt", true);
   final PrintStream ps = new PrintStream(efos);
   // aqui ocorre o redirecionamento de System.err
   System.setErr(ps);
  } catch(final FileNotFoundException e) {
   // tratamento do erro
  }

  FileOutputStream ofos = null;
  try {
   ofos = new FileOutputStream("out.txt", true);
   final PrintStream ps = new PrintStream(ofos);
   // aqui ocorre o redirecionamento de System.out
   System.setOut(ps);
  } catch(final FileNotFoundException e) {
   // tratamento do erro
  }

  System.err.println("Enviando mensagem para um arquivo.");
  System.out.println("Enviando mensagem para outro arquivo.");

  try {
   throw new Exception("Uma exceção gerada para teste");
  } catch(final Exception e) {
   // e.printStackTrace() também é enviado para System.err
   e.printStackTrace();
  }

  // fechando streams
  try {
   if(efos != null) {
    efos.close();
   }
   if(ofos != null) {
    ofos.close();
   }
  } catch(final IOException e) {}
 }
}

Resultado

Após a execução deste código, você terá 2 arquivos criados.
O err.txt com uma linha de texto "Enviando mensagem para um arquivo." e o stacktrace da exceção de teste. Isto é apenas para demostrar que o Java direciona as chamadas printStackTrace para o System.err.
E o out.txt com uma linha de texto "Enviando mensagem para outro arquivo.".
Obs.: o construtor de FileOutputStream está utilizando append, então os arquivos não serão sobrescritos.

Mas, e o console?

Com o código postado acima os textos enviados passarão a aparecer somente nos arquivos citados, mas, talvez, você gostaria de ver os textos também no console da sua IDE favorita enquanto realiza o desenvolvimento e testes da sua aplicação.
Bem, isto é possível com implementação de replicadores de streams. Uma recomendação é a implementação org.apache.commons.io.output.TeeOutputStream disponível na Commons IO da Apache, mas você pode fazer uma pesquisa por TeeStream e irá achar diversas implementações para escolher.

Nenhum comentário:

Postar um comentário

Olá! Antes de postar seu comentário, por favor, observe que comentários técnicos, elogios e sugestões são antecipadamente agradecidos, esclarecimentos sobre os conceitos envolvidos na postagem serão respondidos da melhor forma possível, mas pedidos de ajuda técnica ou suporte individual deverão ser feitos através do formulário de contato. Grato!