1
resposta

Dúvida sobre Java IO

tenho um código aqui que fiz para testes e é gerada uma excessão no segundo método chamado do tipo java.io.IOException: Stream closed, mas se comento a chamada do primeiro método ele funciona, parece que por ja ter manipulado aquele IO por algum motivo não consigo abri-lo novamente é por aí ? Outro erro que aparece é no último método MetodosTestaIO.leituraDeArquivo("leitura.txt", "saida.txt"); que parece que nem é chamado. Alguem consegue me explicar o que está acontecendo com este código:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.util.Scanner;

class MetodosTestaIO{
    public static void escritaNoConsole() throws IOException{
        //Somente escreve no console
        InputStream is = System.in;
        InputStreamReader sr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(sr);

        System.out.println("Digite sua mensagem:\n");
        String linha;
        do{
            linha = br.readLine();
        }while(linha.equals("exit")!=true);
        br.close();
    }

    public static void escritaNoConsole(String arqSaida) throws IOException{
        //escreve no console e imprime em outro arquivo
        InputStream is2 = System.in;
        InputStreamReader sr2 = new InputStreamReader(is2);
        BufferedReader br2 = new BufferedReader(sr2);

        OutputStream os = new FileOutputStream(arqSaida);
        OutputStreamWriter osw = new OutputStreamWriter(os);
        BufferedWriter bw = new BufferedWriter(osw);

        String linha;
        System.out.println("Digite sua mensagem:\n");

        do{
            linha = br2.readLine();
            bw.append(linha);
            bw.newLine();
        }while(linha.equals("exit")!=true);

        br2.close();
        bw.close();
    }

    public static void leituraDeArquivo(String arqEntrada,String arqSaida) throws IOException{
        //copia conteúdo de um arquivo para outro
        Scanner sc = new Scanner(new FileInputStream(arqEntrada));
        PrintStream ps = new PrintStream(arqSaida);
        while(sc.hasNextLine()){
            String linha = sc.nextLine();
            ps.println(linha);
        }
        sc.close();
        ps.close();
    }
    public static void leituraDeArquivo(String arqEntrada) throws IOException{
        //copia conteudo de um arquivo e imprime no console
        Scanner sc = new Scanner(new FileInputStream(arqEntrada));
        PrintStream ps = new PrintStream(System.out);
        while(sc.hasNextLine()){
            String linha = sc.nextLine();
            ps.println(linha);
        }
        sc.close();
        ps.close();
    }

}

public class TestaIO{
    public static void main(String... args) throws IOException{
        System.out.println("Lendo do console:");
        MetodosTestaIO.escritaNoConsole();
        System.out.println("lendo no console e gravando no arquivo");
        MetodosTestaIO.escritaNoConsole("saida.txt");//Joga Exception
        System.out.println("lendo do arquivo e gravando no console");
        MetodosTestaIO.leituraDeArquivo("leitura.txt");
        System.out.println("lendo do arquivo e gravando no arquivo");
        MetodosTestaIO.leituraDeArquivo("leitura.txt", "saida.txt");// parece que não é chamado 
    }
}

Obrigado

1 resposta

Olá Lucas,

Primeiramente, o 2o erro (a linha que aparentemente não é chamada) realmente não é chamada. A partir do momento que seu programa lança uma exception que não é tratada, ele exibe o erro e para de rodar.

Agora sobre o primeiro erro. Repare que na aula, sempre criamos um arquivo novo para mostrar os diferentes modos de utilizar a biblioteca java.io. Isso significa que o erro só ocorre quando você junta eles dessa forma.

O problema na verdade é que ao executar o primeiro modo de leitura do System.in você fecha o stream com br.close(). E no momento que você tentar fazer a leitura por ele no segundo método, você toma uma exception dizendo que o Stream está fechado. (Para conferir, comente o primeiro método de leitura e só execute o segundo. Você verá que ele irá funcionar)

O detalhe aqui, então, é usar o mesmo objeto para fazer as duas leituras e então no final da execução do programa lembrar de fechar o stream.

Você pode criar um atributo nessa classe TestaIO do tipo BufferedReader do System.in, instanciá-la no começo da execução do main, e nos métodos apenas usá-los. Ou seja, 1 BufferedReader para o System.in, e 1 para cada novo arquivo que você queira ler.

Fez mais sentido?

Abraços.