Melhorar performance de leitura de arquivo texto

11 respostas
S

Ola pessoal,
Alguém pode me ajudar?

Meu programa esta com uma grande lentidão para ler arquivos texto. Alguns arquivos chegam a ter 50Mb, tem mais de 50 mil linhas.

Porém eu preciso localizar apenas 1 parâmetro nesse monte de linha.
Segue a maneria que estou tentando fazer. Ocorre tdu OK, porém muito lento.

public static boolean checaarquivo(String arquivo, String parametro) { try { BigFile file = new BigFile(arquivo); for (String line : file) { if (line.indexOf(parametro) != -1) { return true; } } return false; } catch (Exception e) { e.printStackTrace(); return false; }

11 Respostas

E

Que classe é essa “BigFile” ?

S

Um método que le linha por linha.

private BufferedReader _reader;

public BigFile(String arquivo) throws Exception {
    _reader = new BufferedReader(new FileReader(filePath));
}

public void Close() {
    try {
        _reader.close();
    } catch (Exception ex) {
    }
}

public Iterator<String> iterator() {
    return new FileIterator();
}

private class FileIterator implements Iterator<String> {
    private String _currentLine;

    public boolean hasNext() {
        try {
            _currentLine = _reader.readLine();
        } catch (Exception ex) {
            _currentLine = null;
            ex.printStackTrace();
        }
        return _currentLine != null;
    }

    public String next() {
        return _currentLine;
    }
E

Para melhorar um pouco, você pode aumentar o tamanho do buffer do BufferedReader. É um parâmetro a mais:

http://download.oracle.com/javase/6/docs/api/java/io/BufferedReader.html#BufferedReader(java.io.Reader,%20int)

Note que o default é 8KB, você pode aumentar um pouco (digamos 1MB costuma dar bons resultados).

D

Este link pode ajudar: http://java.sun.com/developer/technicalArticles/Programming/PerfTuning/

E

Outra coisa que não gosto nessas classes ___Reader.
Infelizmente, o método readLine sempre retorna uma String, em vez de escrever sobre um StringBuffer passado como parâmetro.
Como resultado disso, se você lê um arquivo de 50MB, o resultado é que 100 MB de bytes resultantes de Strings são alocados e imediatamente disponíveis para coleção no Garbage Collector (uma vez que você despreza as strings lidas, porque só quer achar um padrão dentro delas).
Não sei se é fácil escrever uma BufferedReader2 que tivesse um método readLine2 que escrevesse sobre um StringBuilder a linha dada. O método indexOf de StringBuilder não exerce pressão sobre o Garbage Collector.
Como o Garbage Collector é bem otimizado, na prática gerar e coletar 100 MB de dados não é muito lento, e acho que talvez não valha a pena gastar tempo criando uma BufferedReader2.

I

Eu não sei se você fez isso mas seria mais rápido se você saísse do loop ao achar seu parametro específico já que é apenas 1, além disso leia linha por linha me parece que no seu código você lê o arquivo inteiro e joga em uma String, flw!

I

Cara fiz um código rápido aqui vê se te ajuda

public static boolean buscaParametroArquivo(String caminho, String parametro) throws Exception{ FileReader reader = new FileReader(fileChooser.getSelectedFile()); BufferedReader leitor = new BufferedReader(reader); String linha = ""; //irá guardar linha por linha se for nulo é porque não há mais linhas e sairá do loop while ((linha = leitor.readLine()) != null) { if(linha.contains(parametro)){ return true; //se tiver um parametro retorna true } } return false; //se não achar nada retorna falso }

flw!!

S

Legal esse método,
Teria alguma outra maneira de localizar o parâmetro sem percorrer linha por linha? Como se fosse um select em um banco de dados…

E

Esse arquivo é sempre “novo” (ou seja, a cada vez que você roda esse programa você recebe um arquivo diferente) ou é um arquivo que é sempre consultado, quase não muda, e você pode criar um arquivo de índice para esse seu arquivo - mais ou menos como se fosse um dicionário?

G

Se quiser fazer de um jeito totalmente diferente, existem algumas opções:

  1. Usar java.nio
    Veja um exemplo de uso bem legal aqui: http://gibaholms.wordpress.com/2010/03/25/fora-do-quadrado-java-nio-com-binary-search/

  2. Usar Lucene
    É um engine de busca da Apache, bastante otimizado quanto à performance:
    http://lucene.apache.org/java/docs/index.html
    Leva um tempo para aprender a API, mas talvez valha a pena

G

Importante observação, as 2 maneiras que eu citei dependem da possibilidade de se criar um índice…

Criado 24 de agosto de 2011
Ultima resposta 24 de ago. de 2011
Respostas 11
Participantes 5