quinta-feira, 16 de julho de 2015

Lendo o mesmo arquivo duas vezes

Parece fácil ler um arquivo de texto linha por linha até o fim, para validá-lo por exemplo, e depois voltar ao começo para aí sim processá-lo, mas não foi fácil encontrar a solução! Na documentação do java, eles comentam dos métodos mark e reset do Reader pra voltar a um determinado ponto marcado no arquivo, mas eles não são implementados por todos os tipos de reader e só funcionam quando o arquivo não é muito grande. Veja como você poderia fazer:


import java.io.BufferedReader;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.text.ParseException;
import org.apache.commons.io.IOUtils;

public class LineFileReader {
 
   private BufferedReader in;
   private byte[] bytes;
   private int lineNumber;
 
   public LineFileReader(Reader reader) throws IOException {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      IOUtils.copy(reader, baos);
      bytes = baos.toByteArray();
      in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes)));  
      lineNumber = 0;
   }
 
   public final String readLine() throws IOException {
      lineNumber++;
      return in.readLine();
   }
 
   public int getLineNumber() {
      return lineNumber;
   }

   public void reset() throws ParseException {
      in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes)));
      lineNumber = 0; 
   }

   public static void main(String[] args) throws Exception {
      FileInputStream fileInputStream = new FileInputStream(new File("/home/rafael", "teste.txt"));
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream, "UTF-8"));
      LineFileReader reader = new LineFileReader(bufferedReader);
      String line = reader.readLine();

      while(line != null){
         System.out.println(reader.getLineNumber() + " " + line);
         line = reader.readLine();
      }

      reader.reset();

      line = reader.readLine();
      while(line != null){
         System.out.println(reader.getLineNumber() + " " + line);
         line = reader.readLine();
      }
   }
}