Manipula de arquivos TXT

Bom galera é a minha primeira participação aqui no forum,
trabalho como programador Delphi e estou começando aprender java.
criei um código para manipulação de arquivo txt e gostaria da opnião de vocês se estou fazedo da maneira correta, em fim, todas as sugestões seram bem vindas.

package br.com.fabianogoes.java;
import java.io.*;

public class FileW {
	
	final static int BANCO_PINI = 3;
	final static int BANCO_SIZE = 6;
	
	final static int AGENCIA_PINI = 6;
	final static int AGENCIA_SIZE = 10;
	
	final static int CONTA_PINI = 11;
	final static int CONTA_SIZE = 23;
	
	final static int NUMERO_PINI = 24;
	final static int NUMERO_SIZE = 30;
	
	final static int VALOR_PINI = 33;
	final static int VALOR_SIZE = 50;
	
	public static String getBanco(String linha){
		return linha.substring(BANCO_PINI, BANCO_SIZE);
	}

	public static String getAgencia(String linha){
		return linha.substring(AGENCIA_PINI, AGENCIA_SIZE);
	}

	public static String getConta(String linha){
		return linha.substring(CONTA_PINI, CONTA_SIZE);
	}
	
	public static String getNumero(String linha){
		return linha.substring(NUMERO_PINI, NUMERO_SIZE);
	}

	public static String getValor(String linha){
		return linha.substring(VALOR_PINI, VALOR_SIZE);
	}

	public static void main(String[] args) {
		
		try {
			PrintWriter w = new PrintWriter(new FileWriter("/home/fabiano/Documentos/NewTESTE.CEL", true), true);
			BufferedReader r = new BufferedReader(new FileReader("/home/fabiano/Documentos/TESTE.CEL"));
			
			String linhaRead, linhaWrite;
			
			while((linhaRead = r.readLine()) != null){
				linhaWrite = "BANCO: "   + getBanco(linhaRead)   + " - " +
							 "AGENCIA: " + getAgencia(linhaRead) + " - " +
							 "CONTA: "   + getConta(linhaRead)   + " - " +
							 "NUMERO: "  + getNumero(linhaRead)  + " - " +
							 "VALOR: "   + getValor(linhaRead);
				
				w.println(linhaWrite);

			}
						
			r.close();
			w.close();
			System.out.println("Leitura OK");
			
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}
		
		
	}

}

O correto de um try/catch em IO é assim:

FileWriter fw = null;
PrintWriter w = null;
FileReader fr = null;
BufferedReader r = null;
try {
	fw = new FileWriter("/home/fabiano/Documentos/NewTESTE.CEL", true);
	w = new PrintWriter(fw, true);
	fr = new FileReader("/home/fabiano/Documentos/TESTE.CEL");
	r = new BufferedReader(fr);
	...
	...
	...
} catch (IOException e) {
	throw new Error(e);
} finally {
	if (r != null) {
		try {
			r.close();
		} catch (Exception e) {
			throw new Error(e);
		}
	}
	if (fr != null) {
		try {
			fr.close();
		} catch (Exception e) {
			throw new Error(e);
		}
	}
	if (w != null) {
		try {
			w.close();
		} catch (Exception e) {
			throw new Error(e);
		}
	}
	if (fw != null) {
		try {
			fw.close();
		} catch (Exception e) {
			throw new Error(e);
		}
	}
}

Por q assim mesmo q haja algum erro o finally sempre será executado e os objetos de IO serão fechados sempre.

valeu amigo eduveks
já modifiquei meu código
um abraço!!!

Só para ser chato.
O jeito correto de fechar streams, writers e readers é mais fácil (e se você der uma olhada no código do Eduveks vai ver que ele vai deixar coisas abertas se houver problema ao fechar alguma coisa) é assim:

BufferedWriter bw = null;
BufferedReader br = null;
try {
   bw = new BufferedWriter (new OutputStreamWriter (new FileOutputStream ("saida.txt")));
   br = new BufferedReader (new InputStreamReader (new FileInputStream ("entrada.txt")));
   ....
} catch (IOException ex) {
   ....
} finally {
    // ter problemas ao fechar um arquivo pode ser normalmente ignorado
    if (bw != null) try { bw.close(); } catch (IOException ex) {}
    if (br != null) try {br.close();} catch (IOException ex) {}
}

Se um Stream, Reader ou Writer encapsula outro Stream, Reader ou Writer, você só precisa fechar o mais externo (como eu fiz acima), já que o método close chama o close do stream, reader ou writer encapsulado.
Não é preciso, e aliás está errado, ficar fechando tudo.

[quote=thingol]
e se você der uma olhada no código do Eduveks vai ver que ele vai deixar coisas abertas se houver problema ao fechar alguma coisa[/quote]

por q? :shock:

o finally com os ifs e os closes não chega? Em q situação pode não fazer o close de algum daquele jeito?

ok… fechar só os mais externos é mais fácil, só q nunca tive a certeza absoluta disto por isso jogava mais pelo seguro :stuck_out_tongue:

Acho que ele quiz dizer que caso o código abaixo lance a exception, as outras linhas não vão ser executadas, e possivelmente fechadas:

if (r != null) { try { r.close(); } catch (Exception e) { throw new Error(e); } }

/
||
||
||
Faz sentido.

[quote=thingol]Só para ser chato.
O jeito correto de fechar streams, writers e readers é mais fácil (e se você der uma olhada no código do Eduveks vai ver que ele vai deixar coisas abertas se houver problema ao fechar alguma coisa) é assim:

BufferedWriter bw = null;
BufferedReader br = null;
try {
   bw = new BufferedWriter (new OutputStreamWriter (new FileOutputStream ("saida.txt")));
   br = new BufferedReader (new InputStreamReader (new FileInputStream ("entrada.txt")));
   ....
} catch (IOException ex) {
   ....
} finally {
    // ter problemas ao fechar um arquivo pode ser normalmente ignorado
    if (bw != null) try { bw.close(); } catch (IOException ex) {}
    if (br != null) try {br.close();} catch (IOException ex) {}
}

Se um Stream, Reader ou Writer encapsula outro Stream, Reader ou Writer, você só precisa fechar o mais externo (como eu fiz acima), já que o método close chama o close do stream, reader ou writer encapsulado.
Não é preciso, e aliás está errado, ficar fechando tudo.[/quote]

bom galera,
primeiramente gostaria de agradecer a atenção de todos,
queria dirar mais umas dúvidas:

  • no exemplo do amigo Thingol ele mudou os objetos:
    de PrintWriter para BufferedWriter
    de FileWriter para OutputStreamWriter
    de FileReader para InputStreamReader

porque ?

  • Tambem não entendi o porque dos try/catch dentro do finally

  • a idéia de fechar apenas o objeto mais externo é segura ? o objeto encapsulado será mesmo fechado?

galera, eu sei que para muitos essa dúvidas podem ser simples, mais gostaria de realmente entender a linguagem não apenas decorar.
espero a compreenção de todos.
grato!!!

[quote=Ssalgado]Acho que ele quiz dizer que caso o código abaixo lance a exception, as outras linhas não vão ser executadas, e possivelmente fechadas:

if (r != null) { try { r.close(); } catch (Exception e) { throw new Error(e); } } [/quote]

Háaaa há pois é :stuck_out_tongue:

Dhãnnn!!!

Foi dia de nó cego desculpa ai :stuck_out_tongue:

Não sou um especialista em IO, mas o OutputStreamWriter aceita um OutputStream no construtor, e o FileWriter apenas um arquivo, ou seja o OutputStream é mais versátil, podendo usar até qualquer OutputStream como o System.out. A mesma coisa para o FileReader vs InputStreamReader.

No BufferedWriter vc pode definir o tamanho do buffer, e para usar o PrintWriter apartir do BufferedWriter é assim:

PrintWriter out  = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));

Mas aconselho ler a documentação:

http://java.sun.com/j2se/1.4.2/docs/api/java/io/PrintWriter.html
http://java.sun.com/j2se/1.4.2/docs/api/java/io/BufferedWriter.html
http://java.sun.com/j2se/1.4.2/docs/api/java/io/OutputStreamWriter.html
http://java.sun.com/j2se/1.4.2/docs/api/java/io/InputStreamReader.html
http://java.sun.com/j2se/1.4.2/docs/api/java/io/FileWriter.html
http://java.sun.com/j2se/1.4.2/docs/api/java/io/FileReader.html

Por q o .close() pode dar IOException, e claro tem q ser tratada.

Eu pensava q não, ou melhor eu não tinha a certeza, sempre tive esta duvida, e também sempre tive a preguiça de testar ou pesquisar para tirar o tira teima, mas se o thingol disse ta dito :stuck_out_tongue:

Mas tb é só fazer o teste :wink: