Otimizaçao de codigo java - Ler Arquivo Txt

Fiz dois métodos para ler arquivo txt. Percebi que um é mais rapido que o outro.

public static String lireFichierOptimisee(String fichier) throws IOException { BufferedReader reader = new BufferedReader(new FileReader(fichier)); String texte = ""; while (reader.readLine() != null) { texte += reader.readLine(); } return texte; }

SEGUNDO:

[code]public static String Lecture(String nomfichier) throws IOException {  
  
        String ajout = "";  
        try {  
            File f = new File(nomfichier);  
            FileReader fr = new FileReader(f);  
            BufferedReader br = new BufferedReader(fr);  
              
            try {  
                String line = br.readLine();  
  
                while (line != null) {  
                    line = br.readLine();  
                    ajout += line;  
                }  
  
                br.close();  
                fr.close();  
  
            } catch (IOException exception) {  
                System.out.println("Erreur de lecture: "  
                        + exception.getMessage());  
            }  
        } catch (FileNotFoundException exception) {  
            System.out.println("Pas trouve le fichier");  
        }  
        return ajout;  
    }[/code]  

AI VEM MINHA QUESTAO E SUPOSIÇOES:

O primeiro codigo é mais eficaz pois:

  • é menor
  • nao tem clausulas try / catch
  • crio todos os objetos (new) numa mesma linha

Tem outra coisa que faz o primeiro codigo ser mais eficiente que o segundo? O que?

Obrigada, Veronica

No primeiro você utiliza duas classes principais: BufferedReader e FileReader. Já no segundo, você adiciona uma terceira classe: File. Ao adicionar essa terceira classe, aumenta em um passo o processo do sistema (e mais alocação em memória, pois você cria mais um objeto).

Outra coisa que aumenta o tempo de processamento é o código dentro do while. No primeiro exemplo você só faz uma coisa: concatenar a String lida à sua variável. No segundo, primeiro você atribui a String lida à uma variável e depois concatena esta à outra variável. Comparando os dois loops, o segundo leva muito mais tempo.

O fato de quantidade de linhas ou de ter ou não cláusulas try/catch não influencia no desempenho do seu sistema em quantidades consideráveis para comparação, ou seja, se fizer diferença, é praticamente imperceptível.

Os itens que você apontou não tem relação nenhuma com performance.

O primeiro executa mais rápido porque você só concatena metade das linhas, veja isso:public static String lireFichierOptimisee(String fichier) throws IOException { BufferedReader reader = new BufferedReader(new FileReader(fichier)); String texte = ""; while (reader.readLine() != null) { //le uma linha com o readLine() texte += reader.readLine(); //le outra linha com o readLine(), perdendo o valor da linha antiga } return texte; } Viu? Você teria que alterar seu método, pra utilizar uma String, assim:public static String lireFichierOptimisee(String fichier) throws IOException { BufferedReader reader = new BufferedReader(new FileReader(fichier)); String texto = ""; String linha = ""; while ((linha = reader.readLine()) != null) { texto += linha; } return texto; } Faça o teste com esse código agora

//Para performance você deveria utilizar o StringBuilder e assim o seu .append, exemplo

public static String lireFichierOptimisee(String fichier) throws IOException {      
        BufferedReader reader = new BufferedReader(new FileReader(fichier));      
        StringBuilder texte = new StringBuilder();      
        while (reader.readLine() != null) {    //le uma linha com o readLine()  
            texte.append(reader.readLine());    //le outra linha com o readLine(), perdendo o valor da linha antiga  
        }      
        return texte.toString();      
}     

//EM loops, prefira usar assim

Excelente explicaçao Arthur F. Ferreira…
E eu pensando em numero de linhas e try / catch (que lerda).

Rodrigo Sasaki , testei o metodo sugerido demorou 45 segundos… CARAMBA, porque?
O meu primeiro fez em 10 segundos…

Muito Obrigada.
Verônica

[quote=veronicaveronica]Excelente explicaçao Arthur F. Ferreira…
E eu pensando em numero de linhas e try / catch (que lerda).

Rodrigo Sasaki , testei o metodo sugerido demorou 45 segundos… CARAMBA, porque?
O meu primeiro fez em 10 segundos…

Muito Obrigada.
Verônica[/quote]
Eu expliquei. no seu método você ignora uma linha e grava outra sempre. Metade das linhas do seu arquivo nem estão na String final :slight_smile:

Se quiser otimizar, faça como o marcelo disse, use um StringBuilder, mas cuidado pra não ignorar nenhuma linha

Marcelo.Silva QUE MAGICA é esta com StringBuilder???

Menino, nao deu nem 2 segundos e jah leu todo o arquivo!

Caramba, OBRIGADA
Veronica!

O ideal seria o StringBuilder no segundo código, pois ele faz verificação de erro e chama o close:

[code]public static String Lecture(String nomfichier) throws IOException {

        StringBuider ajout = new StringBuilder();  
        try {  
            File f = new File(nomfichier);  
            FileReader fr = new FileReader(f);  
            BufferedReader br = new BufferedReader(fr);  
              
            try {  
                String line = "";  
  
                while (line != null) {  
                    ajout.append(line);
                    line = br.readLine();  
                }  
  
                br.close();  
                fr.close();  
  
            } catch (IOException exception) {  
                System.err.println("Erreur de lecture: "  
                        + exception.getMessage());  
            }  
        } catch (FileNotFoundException exception) {  
            System.err.println("Pas trouve le fichier");  
        }  
        return ajout.toString();  
    }[/code]

http://imasters.com.br/artigo/7131/java/entendendo-as-classes-string-stringbuilder-e-stringbuffer/

[quote=veronicaveronica]Marcelo.Silva QUE MAGICA é esta com StringBuilder???

Menino, nao deu nem 2 segundos e jah leu todo o arquivo!

Caramba, OBRIGADA
Veronica![/quote]
Cuidado que ele cometeu o mesmo erro que você, está comendo linhas. Se quiser eu tenho um método utilitário aqui que costumo usar: public static String toString(File f, String charset) throws IOException { StringBuilder builder = new StringBuilder(); String linha = null; BufferedReader in = new BufferedReader(new InputStreamReader( new FileInputStream(f), charset)); while ((linha = in.readLine()) != null) { builder.append(linha); } in.close(); return builder.toString(); } Mas como o ViniGodoy disse, verificar o erro pode ser uma boa ideia

Na real nem vi o fluxo, só fui direto na performance kkk

Se estiver usando o Java 7, você pode fazer assim também:

public static String Lecture(String nomfichier) throws IOException { return new String(Files.readAllBytes(nomfichier.toPath())); }

Creio que além de mais curto, seja o jeito mais rápido.

(Existe o método readAllLines também, mas ele retorna um List e também vai exigir um charSet).

Só lembrando também que “ler um arquivo inteiro dentro de uma string” costuma não ser a solução correta para a maior parte dos problemas, até porque essa solução só funciona para arquivos pequenos.

Obrigada galera, vocês sao demais!

Bom Final de Semana.

Verônica