Manipulação de processos em Java

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

[ Hits: 6.547 ]

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

broffice

Conversor de bases decente não essas bostas que tem nesse site.

Ordenar um lista estática seqüencial de complexidade média (método da seleção)

Implementação de lista duplamente encadeada orientada a objetos

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