Dudas con un método que recorre directorios.

Hola comunidad, esta vez vengo con un problema que al inicio a mi me parecía trivial pero ahora me parece mas complejo.
Estoy intentando hacer un programa que recorra ciertos directorios y me devuelva el espacio que ocupan. Ya lo logre hacer, es el siguiente código:

public static double sizeDirectory(File dir) {
        if (dir.isDirectory()) {
            File[] listFiles = dir.listFiles();
            if (listFiles != null) {
                for (File f : listFiles) {
                    if (f.isFile()) {
                        size += (f.length() / 1024.0 / 1024 / 1024 );//Size in GB for Directory.
                        //System.out.println(f.getAbsolutePath());
                    } else {
                        sizeDirectory(f);
                    }
                }
            }
        }
        return size;
    }

Ahora mismo estoy en un GNU/Linux sabor Ubuntu, recién instalado. No hay problema cuando paso la carpeta home o la de descargas o similares, lo que me tiene atascado es que cuando paso el directorio raiz "/". Tarda muchísimo, lo he dejado por una hora y no termina.

¿Qué es esta mal en mi código? ¿Que debería tener en cuenta al momento de hacer este tipo de operaciones de lectura? Algún tema en especial que me puedan recomendar para orientarme mejor? ¿Estoy olvidando algo básico? Jajaja. Bueno, espero sus comentarios.

Saludos.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

Enlaces simbólicos

 

Quizás funcione mejor si evitas los enlaces simbólicos (Symbolic link). Por cierto, Apache Commons IO tiene una clase, org.apache.commons.io.FileUtils, con varios métodos (sizeOf-) que calculan el tamaño (en bytes) de un archivo o directorio. Puedes echar un vistazo al código de esta clase.

~~~

Imagen de Jose Manuel

¿Un algoritmo mas eficiente?

Estoy evitando los enlaces simbólicos, sigue sin funcionar de manera rápida. Supongo que estoy haciendo un FOR de los buenos. Debe haber una manera (algoritmo) que sea mas rápido para realizar este tipo de operaciones y yo no me lo se.

Saludos.

The du Command

 

Pues solamente que ejecutes el comando du desde Java.

~~~

Imagen de ezamudio

long

Te recomiendo que no guardes estado afuera, solamente necesitas que el método devuelva el tamaño del archivo o directorio en bytes y ya. Al final luego haces la conversión a GB o lo que sea.

public long size(File f) {
  if (f.isFile()) {
    //TODO si es symlink devuelve 0
    return f.length();
  }
  long size=0;
  for (File sub:f.listFiles()) {
    if (sub.isFile()) {
      size+=sub.length();
    } else {
      size+=size(sub);
    }
  }
  return size;
}