Manipulando Arquivos de Propriedades

Neste artigo utilizaremos a classe java.util.Properties para a manipulação de arquivos de propriedades. Veremos como escrever e ler nestes arquivos. Esta classe nos permite criar dois tipos de arquivos de propriedades, o .properties e o .xml. Ambos os arquivos, por exemplo, podem ser vistos em configurações utilizadas no HIbernate, o hibernate.properties e o hibernate.cfg.xml.

Uma das vantagens da utilização de arquivos de propriedades é separar configurações que podem ser alteradas a qualquer tempo do código Java. Assim, não seria necessário alterar o código Java sempre que seja necessária uma alteração nas configurações.

Os arquivos de propriedades são muito utilizados em sistemas desenvolvidos em Java. Temos configurações de internacionalização, configurações de email, jdbc, logs, entre outras. Fica a cargo do desenvolvedor saber quando é necessária sua utilização.

1. Classe JdbcConnection

Vamos criar uma classe chamada JdbcConnection, onde criaremos atributos utilizados para conexões do tipo JDBC.

Listagem 1. Classe JdbcConnecion
public class JdbcConnection {
    private String user;
    private String pass;
    private String driver;
    private String url;
    private String dataBase;

    // gerar os métodos getters and setters
}

2. Arquivo .properties

Vamos agora criar uma classe de testes para criar e ler nosso arquivo de propriedades. Um arquivo de propriedades tem o seguinte formato, chave e valor. À direita temos a chave e a esquerda temos o valor. Um exemplo pode ser visto na listagem 2.

Listagem 2. Arquivo jdbc.properties
jdbc.dataBase = myDataBase
jdbc.driver = com.mysql.jdbc.Driver
jdbc.pass = admin01
jdbc.url = jdbc\:mysql\://localhost\:3306/
jdbc.user = root

Vamos então criar a classe PropertiesTest e nela iremos criar três métodos, o método main() é claro, e mais um método para criação do arquivo e um método para leitura do arquivo.

Crie a classe conforme a listagem 3.

Listagem 3. Classe PropertiesTest

import java.io.*;
import java.util.Properties;

public class PropertiesTest {

    public static void main(String[] args) {
        JdbcConnection jdbc = new JdbcConnection();
        jdbc.setUser("root");
        jdbc.setPass("admin01");
        jdbc.setDriver("com.mysql.jdbc.Driver");
        jdbc.setUrl("jdbc:mysql://localhost:3306/");
        jdbc.setDataBase("myDataBase");
    }

}

Criamos uma inst ncia da classe JdbcConnection e então criamos um objeto com as informações que farão parte do nosso arquivo.

Vamos agora criar o método que irá gerar o arquivo jdbc.properties.

Listagem 4. Método de criação do arquivo jdbc.properties
private static void criarPropriedades(JdbcConnection jdbc) {
	//Cria um objeto da classe java.util.Properties
	Properties properties = new Properties();

	//setando as propriedades(key) e os seus valores(value)
	properties.setProperty("jdbc.user", jdbc.getUser());
	properties.setProperty("jdbc.pass", jdbc.getPass());
	properties.setProperty("jdbc.driver", jdbc.getDriver());
	properties.setProperty("jdbc.url", jdbc.getUrl());
	properties.setProperty("jdbc.dataBase", jdbc.getDataBase());

	try {
		//Criamos um objeto FileOutputStream            
		FileOutputStream fos = new FileOutputStream("C:\\jdbc.properties");
		//grava os dados no arquivo
		properties.store(fos, "FILE JDBC PROPERTIES:");
		//fecha o arquivo
		fos.close();
	} catch (IOException ex) {
		System.out.println(ex.getMessage());
		ex.printStackTrace();
	}
}

Criamos um objeto properties onde setamos as propriedades através do método setProperty(). Como já explicado anteriormente, o primeiro valor é a chave ou o nome da propriedade, e o segundo valor é o valor da propriedade propriamente dita.

O objeto fos cria o fluxo para escrever no arquivo definido em seu construtor. O método store() é quem faz a mágica da classe Properties, nela passamos como parametro o objeto fos e uma descrição para o arquivo. Caso não queira setar uma descrição, o parametro pode ser null.

Após a execução deste método, teremos a seguinte saída, que pode ser visualizada na listagem 5.

Listagem 5. Arquivo jdbc.properties
#FILE JDBC PROPERTIES:
#Wed Mar 30 15:48:34 BRT 2011
jdbc.url = jdbc\:mysql\://localhost\:3306/
jdbc.driver = com.mysql.jdbc.Driver
jdbc.user = root
jdbc.dataBase = myDataBase
jdbc.pass = admin01

Agora vamos criar um método para ler as propriedades deste arquivo. Para isso, faça como na listagem 6.

Listagem 6. Lendo arquivo jdbc.properties
private static void lerPropriedades() {
	Properties properties = new Properties();

	try {
		//Setamos o arquivo que vai ser lido
		FileInputStream fis = new FileInputStream("C:\\jdbc.properties");
		//metodo load faz a leitura atraves do objeto fis
		properties.load(fis);
	} catch (IOException e) {
		e.printStackTrace();
	}

	//Captura o valor da propriedade, atraves do nome da propriedade(Key)
	String p1 = properties.getProperty("jdbc.user");
	String p2 = properties.getProperty("jdbc.pass");
	String p3 = properties.getProperty("jdbc.driver");
	String p4 = properties.getProperty("jdbc.url");
	String p5 = properties.getProperty("jdbc.dataBase");
	System.out.println(p1 + "\n" + p2 + "\n" + p3 + "\n" + p4 + "\n" + p5);
}

Se para setar as propriedades usavamos o método setProperty(), agora para ler precisamos usar o método getProperty(), desta vez, setamos apenas a chave referente ao valor que queremos recuperar no arquivo.

Execute o método de leitura e veja no console que terá uma saída com os valores das propriedades existentes no arquivo jdbc.properties.

3. Arquivo .xml

Vamos agora criar o arquivo de propriedades, mas não no formato .properties, e sim no formato .xml. Um exemplo de arquivo de propriedades no formato XML pode ser visualizado na figura 1.

Arquivo jdbc.xml

Figura 1 – Arquivo jdbc.xml

Para gerar o arquivo XML precisamos apenas trocar o método store() pelo método storeToXML(). E vamos passar mais um par metro que seta o encoding do XML.

Também deve ser alterado o tipo de arquivo de .properties para .xml, não esqueça de efetuar esta troca. Confira na listagem 7 a chamada ao método storeToXML().

Listagem 7. Método storeToXML()
properties.storeToXML(fos, "FILE JDBC XML:", "ISO-8859-1");

Para efetuar a leitura do arquivo XML precisamos trocar o método load() pelo método loadFromXML(), conforme a listagem 8.

Listagem 8. Método loadFromXML()
properties.loadFromXML(fis);

Muito simples com certeza. Agora você pode decidir qual tipo de arquivo prefere utilizar nas diversas aplicações que fará.

4. Ordenando o conteúdo dos arquivos

Como você pode notar, se ainda não notou vai perceber agora, o arquivo não fica organizado. Tanto o arquivo do tipo properties quanto o do tipo XML tem suas chaves fora de ordem. Não que isso faça diferença, mas é muito melhor ter um arquivo organizado de alguma forma.

Podemos criar o arquivo em ordem alfabética, para isso vamos criar uma nova classe com um método para cada tipo de arquivo que será criado.

Listagem 9. Classe para executar a ordenação dos arquivos
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Properties;
import java.util.TreeSet;
import java.util.Set;   

public class SortedKey {

    public void sortedProperties(Properties properties, File file, String comments) {
        Properties props = new Properties() {
            @Override
            public synchronized Enumeration<Object> keys() {
                return Collections.enumeration(
                          new TreeSet<Object>(super.keySet())
                 );
            }
        };

        props.putAll(properties);

        try {
            props.store(new FileOutputStream(file), comments);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void sortedXml(Properties properties, File file, String comments, String encoding) {
        Properties props = new Properties() {
            @Override
            public Set<Object> keySet() {
                return Collections.unmodifiableSet(
                          new TreeSet<Object>(super.keySet())
                 );
            }
        };

        props.putAll(properties);

        try {
            props.storeToXML(new FileOutputStream(file), comments, encoding);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Como a classe java.util.Properties herda a classe java.util.Hashtable que não é um tipo de coleção que possui ordenação, precisamos fazer a ordenação de uma forma um pouco mais complicada, mas nem tanto assim.

Para ordenar o arquivo .properties criamos uma classe anônima do tipo Properties, e nesta classe criamos um método que retorna uma coleção do tipo java.util.Enumeration, que é um interface. Esta coleção obtemos através do retorno de um método da classe java.util.Collections, chamado enumeration(). Neste método passamos como parametro um objeto do tipo java.util.TreeSet, que é uma coleção ordenada por padrão.

Adicionamos nesta classe anônima, através de seu o objeto props, o objeto properties recebido como parametro, e então, ela irá ordenar por ordem alfabética as chaves de nosso arquivo. E por fim o arquivo será salvo.

A ordenação para o arquivo .xml funciona quase da mesma forma, pelo menos utiliza o mesmo principio, criação da classe anônima e de um método que irá devolver o objeto ordenado.

Para testar estes dois métodos, vamos fazer criar um novo método que salva nossos arquivos, veja na listagem 10.

Listagem 10. Alterações para ordenar conteúdo dos arquivos
private static void criarArquivosOrdenados(JdbcConnection jdbc) {
	Properties properties = new Properties();
	properties.setProperty("jdbc.user", jdbc.getUser());
	properties.setProperty("jdbc.pass", jdbc.getPass());
	properties.setProperty("jdbc.driver", jdbc.getDriver());
	properties.setProperty("jdbc.url", jdbc.getUrl());
	properties.setProperty("jdbc.dataBase", jdbc.getDataBase());

	new SortedKey().sortedProperties(
			 properties, "C:\\jdbc.properties", "Arquivo de Propriedades"
	 );

	 new SortedKey().sortedXml(
			 properties, "C:\\jdbc.xml", "Arquivo XML", "ISO-8859-1"
	 );
}

Executando este novo método teremos uma saída diferente das anteriores, veja na figura 2 a diferença entre os arquivos com e sem ordenação.

Comparação entre arquivos

Figura 2 – Comparação entre arquivos

Veja que como usamos a palavra jdbc na frente, a ordenação é feita pela segunda palavra após o ponto, de forma alfabética.

Conclusão

Neste tutorial vimos como criar e ler um arquivo de propriedades através da classe java.util.Properties, sendo ele do tipo .properties ou .xml. Também vimos como ordenar através das chaves o conteúdo escrito nestes arquivos.

Não deixe de ler a documentação das classes e interfaces utilizadas para entender como funcionam os métodos internos, é sempre uma boa prática.

Saiba mais

Ballem

Marcio Ballem é bacharel em Sistemas de Informação pelo Centro Universitário Franciscano em Santa Maria/RS. Tem experiência com desenvolvimento Delphi e Java em projetos para gestão pública e acadêmica. Possui certificação em Java, OCJP 6.

Você pode gostar...