Calculo de pastas e subpastas com desempenho ou segundo plano

Olá, estou fazendo uma aplicação que envolve calculo do tamanho de um diretorio incluindo todos arquivos e todas os subdiretorios.
Já pesquisei bastante mas não encontro nada que resolva o problema com eficiencia e agilidade.

O que encontrei foram metodos recursivos, o que demora muito tempo para calcular:

    public long calculaFile(File file) {
        if (file.isFile()) {

            tamanho += file.lenght();
			
         else {

            file.listFiles(this);
        }
    }
}

Talvez não tenha uma solução mais rapida, então estou pensando em colocar esse calculo em segundo plano, talvez utilizando threads, pois não quero que trave o programa enquanto calcula um File, preciso que o usuario continue selecionando outros Files ou fazendo outras coisas enquanto isso ele calcula para que depois do fim do calculo ele atualize o banco de dados com o tamanho final de todos os arquivos selecionados, mas não sei como fazer este calculo em “segundo plano” sem que trave o programa.

Se alguem tiver alguma idéia para compartilhar, fico grato.

Faz com várias threads com ‘retorno’ … aí vc coloca um jprogress bar…
se nao precisar, joga as threads msmo :wink:

[quote=jeanKateka]Olá, estou fazendo uma aplicação que envolve calculo do tamanho de um diretorio incluindo todos arquivos e todas os subdiretorios.
Já pesquisei bastante mas não encontro nada que resolva o problema com eficiencia e agilidade.

O que encontrei foram metodos recursivos, o que demora muito tempo para calcular:

    public long calculaFile(File file) {
        if (file.isFile()) {

            tamanho += file.lenght();
			
         else {

            file.listFiles(this);
        }
    }
}

Talvez não tenha uma solução mais rapida, então estou pensando em colocar esse calculo em segundo plano, talvez utilizando threads, pois não quero que trave o programa enquanto calcula um File, preciso que o usuario continue selecionando outros Files ou fazendo outras coisas enquanto isso ele calcula para que depois do fim do calculo ele atualize o banco de dados com o tamanho final de todos os arquivos selecionados, mas não sei como fazer este calculo em “segundo plano” sem que trave o programa.

Se alguem tiver alguma idéia para compartilhar, fico grato.
[/quote]

Infelizmente isso é lento mesmo, como você pode ver se pegar o Windows Explorer e clicar sobre um diretório grande com o botão direito e, no menu, escolher “Propriedades” e ficar observando ele mostrar quantos arquivos e qual é o tamanho dos arquivos somados. Por exemplo, na minha máquina o Windows ficou 10 segundos para me mostrar o valor final - veja a figura abaixo.
(Acho que o Java iria demorar uns 15s nesse caso :frowning: )

[quote=d34d_d3v1l]Faz com várias threads com ‘retorno’ … aí vc coloca um jprogress bar…
se nao precisar, joga as threads msmo :wink:

[/quote]

o que mudaria se eu criar 1 thread apenas e deixar ela lendo em segundo plano, ou criar várias threads, será que isso aumenta o desempenho ?

Use uma só - já pensou no tamanho da encrenca se você criar N threads recursivamente?

Como é que você vai controlar isso de maneira trivial? (No Java 7 você pode tentar usar fork-join mas o algoritmo não é trivial).

Sem contar que percorrer o disco recursivamente não deve ser tão mais rápido se você dividir o trabalho entre várias threads :frowning: - em particular, se for um DVD ou um CD, é mais lento, porque os diretórios estão gravados em forma sequencial no início do DVD. Se você tentar percorrer recursiva e fora de sequência vai demorar bem mais.

Hum… só lembrando. Se você percorrer recursivamente um diretório bem grande pela primeira vez, vai ver que o tempo é bem maior que quando você o percorre pela segunda vez - é porque os diretórios foram trazidos para o cache de disco, e então na hora de checar pela segunda vez o seu programa nem vai ler mais do disco, e sim do cache de disco. Portanto é um pouco difícil de avaliar o desempenho entre algoritmos diferentes.

Além disso, acho que é mais rápido você fazer uma “breadth-first walk” que uma “depth-first walk” na árvore de diretórios.

Outra coisa - para pôr uma “progress bar” não é tão trivial, porque você tem uma busca recursiva - você, na verdade, nem sabe quantos por cento você já concluiu de seu cálculo; pode ter uma idéia aproximada mas não um cálculo exato.

pode cree…

acho que a progress bar entraria mais no caso de cópia de arquivos…onde ja se tem o tamanho total.