DirectoryStream‹Path› перечисляет файлы в случайном порядке

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

Они нужны мне последовательно, как img0,img1.....imgn
Как мне это сделать?
**Я разработал собственную схему сортировки, но получаю исключение. Кодировка приведена здесь: "

try{
                int totalImages = 0;
                int requiredImage = 0;
                jpegFiles = Files.newDirectoryStream(Paths.get(pathToPass).getParent(), "*.JPG");
                Iterator it = jpegFiles.iterator();
                Iterator it2 = jpegFiles.iterator();
                Iterator it3 = jpegFiles.iterator();
                while(it.hasNext()){
                    it.next();
                    totalImages++;
                }
                System.out.println(totalImages);
                sortedJpegFiles = new String[totalImages];
                while(it2.hasNext()){
                    Path jpegFile = (Path)it2.next();
                    String name = jpegFile.getFileName().toString();
                    int index = name.indexOf(Integer.toString(requiredImage));
                    if(index!=-1){
                        sortedJpegFiles[requiredImage] = jpegFile.toString();
                    }
                    requiredImage++;
                }
                for(String print : sortedJpegFiles){
                    System.out.println(print);
                }

            }catch(IOException e){
                e.printStackTrace();  
            }  

Исключение:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Iterator already obtained
    at sun.nio.fs.WindowsDirectoryStream.iterator(Unknown Source)
    at ScreenshotDemo.SCapGUI$VideoCreator.run(SCapGUI.java:186)
    at ScreenshotDemo.SCapGUI$1.windowClosing(SCapGUI.java:30)
    at java.awt.Window.processWindowEvent(Unknown Source)
    at javax.swing.JFrame.processWindowEvent(Unknown Source)
    at java.awt.Window.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$200(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

person Dummy Derp    schedule 13.09.2012    source источник
comment
Это не случайно, они кажутся мне лексикографически упорядоченными.   -  person Keppil    schedule 13.09.2012
comment
Итак, сортируйте имена файлов самостоятельно на основе ваших критериев?   -  person matt b    schedule 13.09.2012
comment
для этого нет встроенного метода?   -  person Dummy Derp    schedule 13.09.2012
comment
1. получить имена файлов. 2. вызовите Collections.sort() с вашим пользовательским компаратором, который реализует вашу пользовательскую логику сортировки.   -  person matt b    schedule 13.09.2012
comment
Работаем над пользовательской логикой, ребята. Подожди :)   -  person Dummy Derp    schedule 13.09.2012


Ответы (2)


Пользовательский компаратор

Вам придется извлечь числовую часть, возможно, используя какое-то регулярное выражение, а затем использовать ее для сортировки. Пользовательский Comparator может инкапсулировать пользовательский числовой сравнение для вас.

import java.util.*;
import java.util.regex.*;

// Sort strings by last integer number contained in string.
class CompareByLastNumber implements Comparator<String> {
    private static Pattern re = Pattern.compile("[0-9]+");
    public boolean equals(Object obj) {
        return obj != null && obj.getClass().equals(getClass());
    }
    private int num(String s) {
        int res = -1;
        Matcher m = re.matcher(s);
        while (m.find())
            res = Integer.parseInt(m.group());
        return res;
    }
    public int compare(String a, String b) {
        return num(a) - num(b);
    }
    public static void main(String[] args) {
        Arrays.sort(args, new CompareByLastNumber());
        for (String s: args)
            System.out.println(s);
    }
}

Избегайте IllegalStateException

Ссылаясь на ваш обновленный вопрос: исключение, с которым вы сталкиваетесь, связано с тем, что вы пытаетесь повторить DirectoryStream несколько раз. Цитата из ссылки:

Хотя DirectoryStream расширяет Iterable, это не Iterable общего назначения, поскольку он поддерживает только один Iterator; вызов метода итератора для получения второго или последующего итератора выдает IllegalStateException.

Поэтому поведение, которое вы видите, ожидаемо. Вы должны собрать все свои файлы в единый список. Что-то в этом роде:

List<Path> jpegFilesList = new ArrayList<>();
while (Path p: jpegFiles)
  jpegFilesList.add(p);
sortedJpegFiles = new String[jpegFilesList.size()];
for(Path jpegFile: jpegFilesList) {
  …
}

Обратите внимание, что эта проблема, связанная с IllegalStateException, несколько отличается от исходного вопроса, который вы задали. Так что было бы лучше в отдельный вопрос. Помните, что SO — это не форум. Поэтому, пожалуйста, придерживайтесь одной проблемы на каждый вопрос.

person MvG    schedule 13.09.2012
comment
Хорошо, у меня есть идея. Выберите путь, используйте getFileName, затем используйте indexOf, чтобы получить числовую часть и отсортировать на ее основе. Это слишком общее. Можете ли вы уточнить его? - person Dummy Derp; 13.09.2012
comment
Хорошо, я получаю исключение «Итератор уже получен». Как повторно использовать итератор? - person Dummy Derp; 13.09.2012
comment
Как правило, вы не используете итератор повторно, вы создаете новый из коллекции. Если вы все еще используете такой код, как этот, вам не следует пытаться перебирать DirectoryStream более одного раза. Обратите внимание, что в справочнике по API указано столько. Вместо этого создайте новый список из этого потока и отсортируйте его. - person MvG; 13.09.2012
comment
Исключение в потоке AWT-EventQueue-0 java.lang.IllegalStateException: итератор уже получен в sun.nio.fs.WindowsDirectoryStream.iterator(неизвестный источник) в ScreenshotDemo.SCapGUI$VideoCreator.run(SCapGUI.java:186) в ScreenshotDemo.SCapGUI $1.windowClosing(SCapGUI.java:30) - person Dummy Derp; 13.09.2012

Файлы упорядочены лексикографически, что может показаться неестественным для человека, но вполне логичным для компьютера.
Есть несколько алгоритмов сортировки по "человеческой логике", если не хотите делать это самостоятельно, один пример Алгоритм Alphanum.

person Keppil    schedule 13.09.2012