Самая быстрая возможность перечисления каталога и получения URL каждого файла в Java - PullRequest
5 голосов
/ 05 октября 2010

Я планирую выполнить стандартную команду списка, чтобы получить вектор или список содержимого каталога.

Я знаю, что это легко с помощью

File f = new File("C:/testDir");
File[] files = f.listFiles();

Проблемав том, что мне нужен список / массив / вектор URL-адресов.Поэтому мои мысли заключались в том, чтобы преобразовать файлы в URL.С библиотекой org.apache.commons.io.FileUtils это возможно с помощью следующего простого кода:

URL[] urls = FileUtils.toURLs(files);

Это делает именно то, что мне нужно, но, к сожалению, очень медленно (особенно для каталогов с тысячами файлов)), хотя он просто использует цикл for и анализирует каждый объект File с помощью метода "toURL ()".

Кто-нибудь знает способ сделать эту задачу с большей производительностью?

Ответы [ 5 ]

8 голосов
/ 05 октября 2010

Единственная простая оптимизация - сокращение создания объектов, что приведет к незначительному повышению производительности.Вместо использования listFiles(), который создает целый ряд объектов File, используйте list(), чтобы получить массив String, содержащий только имена файлов, а не пути, и создать URL-адреса напрямую.В этом случае создание и хранение строк будут иметь меньше служебных данных.Манипуляции со строками, очевидно, можно было бы сделать быстрее и более правильными, хотя, вероятно, это не будет иметь большого значения.

2 голосов
/ 05 октября 2010

Создайте новый объект URL, вместо того, чтобы вызывать метод toUrl (), кажется более эффективным.Я проверил это:

    File parent=new File("./doc");
    File[] listado=parent.listFiles();
    long t0=0L;
    try {
       t0=System.currentTimeMillis();
       for(int k=0;k<10000;k++) {
        URL[] listaArchivos=new URL[listado.length];
        for (int i = 0; i < listado.length; i++) {
            listaArchivos[i]=listado[i].toURL();
        }
       } 
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println("Files:"+listado.length+"; Time 1: "+(System.currentTimeMillis()-t0)+" ms");


    try {
        t0=System.currentTimeMillis();
        for(int k=0;k<10000;k++) {
            URL[] listaArchivos=new URL[listado.length];
            for (int i = 0; i < listado.length; i++) {
                listaArchivos[i]=new URL("file://"+listado[i].getAbsolutePath());
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }           
    System.out.println("Files:"+listado.length+"; Time 2: "+(System.currentTimeMillis()-t0)+" ms");

Мой вывод:

Files:14; Time 1: 1985 ms
Files:14; Time 2: 516 ms
1 голос
/ 05 октября 2010

Другие люди ответили, что построение URL-адресов с помощью конкатенации строк (например, "file://" + dirPath + "/" + file.getName() намного быстрее, чем вызов File.toURI().toString(). Например, OP сообщает о 5-кратном ускорении. Я задавался вопросом, почему существует такая разница.

По-видимому, одна из причин заключается в том, что метод toURI() проверяет, является ли каталог this, и добавляет /, если это так. Следствие заключается в том, что URL-адрес для каталога, созданного конкатенацией String не будет иметь завершающий /.

Существует еще одна оговорка с созданием "file:" URL-адресов путем конкатенации строк, то есть если имена в пути к файлу содержат зарезервированные символыспецификации URL / URI), то конкатенация строк может привести к неправильному формату URL / URI. Зарезервированные символы обычно должны быть экранированы %. Кроме того, в Windows не совсем ясно, как буквы дисков должны быть представлены в URL "file:".

1 голос
/ 05 октября 2010

Если у вас действительно так много файлов, вы можете использовать несколько потоков.Каждый из n потоков конвертирует файлы 1 / n.

Чтобы это было эффективным, вам нужно действительно много файлов.

1 голос
/ 05 октября 2010

Ваше решение в порядке, и вам не нужно беспокоиться о производительности, если у вас нет десятков тысяч файлов в этом каталоге.

Оптимизация производительности может заключаться в кэшировании массива URL с, если эта функция используется часто.

Тем не менее - измерьте, сколько нужно, чтобы выполнить это в каталоге с файлами 2k, а затем оптимизируйте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...