Manipulação de processos em Java

Publicado por Cristiano Costa (última atualização em 07/04/2010)

[ Hits: 6.207 ]

Download iProcess.java




Uma classe para a manipulação de processos em Java, com suporte a criação, leitura do STDOUT e STDERR, comparação entre 2 processos (usando equals()), clonagem etc.

  



Esconder código-fonte

/***********************************************************
 * Esta classe esta sob a licenca Creative Commons 3.0:    
 * http://creativecommons.org/licenses/by/3.0/br/legalcode 
 *                                                         
 * @author Cristiano Bernardes                             
 * @since 04/04/2010                                       
 * @version 1.0.0.0.0                                      
 ***********************************************************/

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * Classe para a execuçao de processos
 * 
 * @author Cristiano Bernardes
 * @since 04/04/2010
 * @version 1.0.0.0.0
 */
public class iProcess
             implements Cloneable {

    /**
     * A instancia do processo.
     */
    private Process process;

    /**
     * A linha de comando (tipo UNIX) usada para iniciar o processo.
     */
    private String lineCMD;

    /**
     * true, se o processo pode ser clonado ou false, se o processo nao pode.
     */
    private boolean cloneable;

    /**
     * O stdout do processo (Sendo lido por um BufferedReader).
     */
    private BufferedReader stdout;

    /**
     * O stderr do processo (Sendo lido por um BufferedReader).
     */
    private BufferedReader stderr;

    /**
     * Construtor padrao.
     * Inicia o processo pela sua linha de comando (tipo UNIX) e informando se o processo
     * pode ser clonado.
     *
     * @author Cristiano Bernardes
     * @since 04/04/2010
     * @version 1.0.0.0.0
     *
     * @param proc A linha de comando (tipo UNIX)
     * @param cloneable true, se pode ser clonado, false se nao pode
     */
    public iProcess(String proc, boolean cloneable) {
        try {
            this.process = Runtime.getRuntime().exec(proc);
            this.lineCMD = proc;
            this.cloneable = cloneable;

            InputStream StreamEntrada = this.process.getInputStream();
            InputStream StreamErro = this.process.getErrorStream();

            stdout = new BufferedReader(new InputStreamReader(StreamEntrada));
            stderr = new BufferedReader(new InputStreamReader(StreamErro));
        }
        catch(IOException ex){ System.err.println("Erro de IO com o processo: "+this.lineCMD); }
    }

    /**
     * Retorna o comando utilizado para iniciar o processo
     *
     * @author Cristiano Bernardes
     * @since 04/04/2010
     * @version 1.0.0.0.0
     *
     * @return O comando utilizado para iniciar o processo
     */
    public String getLineCMD() {
        return lineCMD;
    }

    /**
     * Retorna o STDOUT do processo
     *
     * @author Cristiano Bernardes
     * @since 04/04/2010
     * @version 1.0.0.0.0
     *
     * @return O STDOUT do processo
     */
    public BufferedReader getSTDOUT() {
        return this.stdout;
    }

    /**
     * Retorna o STDERR do processo
     *
     * @author Cristiano Bernardes
     * @since 04/04/2010
     * @version 1.0.0.0.0
     * 
     * @return O STDERR do processo
     */
    public BufferedReader getSTDERR() {
        return this.stderr;
    }

    /**
     * Le uma linha do STDOUT do processo.
     * Retorna a linha lida ou null caso nao haja linhas para serem lidas.
     *
     * @author Cristiano Bernardes
     * @since 04/04/2010
     * @version 1.0.0.0.0
     * 
     * @return A linha lida ou null caso nao haja linhas para serem lidas
     */
    public String readLine(){
        try {
            if(this.stdout.ready())
                return this.stdout.readLine();
            else
                return null;
        }
        catch(IOException ex){ System.err.println("Erro de IO com o processo: "+this.lineCMD); return null; }
    }

    /*
     * Overrides ------------------------------------------------------------------
     */

    /**
     * Retorna uma simples representaçao de caracteres com informaçoes sobre este
     * processo. (E um processo de mao unica, nao pode ser retornado).
     *
     * @author Cristiano Bernardes
     * @since 04/04/2010
     * @version 1.0.0.0.0
     *
     * @return Representaçao em String com informaçoes sobre o processo
     */
    @Override
    public String toString() {
        return "Processo: "+this.lineCMD;
    }

    /**
     * Compara o processo executado por esta instancia com outro processo, retorna true,
     * se ambos forem a mesma linha de comando, caso contrario, retorna false.
     *
     * @author Cristiano Bernardes
     * @since 04/04/2010
     * @version 1.0.0.0.0
     *
     * @param obj O objeto a ser comparado
     * @return true, se forem a mesma linha de comando, false, se o contrario
     */
    @Override
    public boolean equals(Object obj) {
        if(!(obj instanceof iProcess)){
            return false;
        }

        return ((iProcess) obj).lineCMD.equals(this.lineCMD);
    }

    /**
     * Gera um hashCode (representaçao de hash desta instancia).
     *
     * @author Cristiano Bernardes
     * @since 04/04/2010
     * @version 1.0.0.0.0
     * 
     * @return o hash code
     */
    @Override
    public int hashCode() {
        int hash = 3;
        hash = 83 * hash + (this.lineCMD != null ? this.lineCMD.hashCode() : 0);
        return hash;
    }

    /**
     * Gera um clone exato desta instancia, sendo que nao e esta.
     *
     * @author Cristiano Bernardes
     * @since 04/04/2010
     * @version 1.0.0.0.0
     *
     * @return Um clone exato desta instancia.
     * @throws CloneNotSupportedException Se nao for permitida a clonagem.
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        if(!this.cloneable)
            throw new CloneNotSupportedException("Clonagem nao e permitida nesta instancia.");

        return new iProcess(this.lineCMD, true);
    }

    /**
     * Metodo chamado pelo coletor de lixo quando este detecta que nao ha mais
     * nada que carrega esta instancia.
     * Simplesmente fecha as conexoes e desinstancia as variaveis.
     *
     * @author Cristiano Bernardes
     * @since 04/04/2010
     * @version 1.0.0.0.0
     * 
     * @throws Throwable Nao e lancado
     */
    @Override
    protected void finalize() throws Throwable {
        this.stderr.close();
        this.stdout.close();

        this.process.getInputStream().close();
        this.process.getOutputStream().close();
        this.process.getErrorStream().close();
        this.process.destroy();

        this.stderr = null;
        this.stdout = null;
        this.lineCMD = null;
        this.process = null;
    }

}

Scripts recomendados

Instalando java no ubuntu, fácil e rápido...

Zipando Pasta ou Arquivo

HACK :: Microsoft SQL 2000 JDBC Driver

Exemplo BubleSort

J2ME - Simples teste de unicode


  

Comentários
[1] Comentário enviado por pacman em 07/04/2010 - 20:07h

Ola

Cuidado com o finalize, o close dos Streams pode lançar uma IOException e, nesse caso, o objeto fica inelegivel para o garbage collector.

Outra coisa é a necessidade de esconder as exceptions: quem chama deveria tratar, ou eu posso ter um problema no construtor ou no readline e só descubro quando olho a stderr?

Por fim, não entendo pq ter um atributo cloneable. Seria mais simples ter um construtor que receba um objeto do tipo iProcess e copie o seu estado de forma explicita.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts