Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
112 views
in Technique[技术] by (71.8m points)

java - DirectoryStream<Path> lists files in a haphazard manner

I have to retrieve a set of JPG files from the folder so that I can create a movie with it. The problem is that the files are listed in a haphazard manner and hence are processed in a haphazard manner. Here is a screenshot:
enter image description here

I need them in a sequential manner as img0,img1.....imgn
How do I do that?
**I deveopled a custom sorting scheme but I get an exception. The coding is given here: "

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:

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)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Custom Comparator

You'll have to extract the number part, possibly using some regular expression, and then use that to sort. A custom Comparator might encapsulate the custom numerical comparison for you.

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);
    }
}

Avoiding the IllegalStateException

Referring to your updated question: the exception you encounter is because you attempt to iterate over the DirectoryStream multiple times. Quoting from its reference:

While DirectoryStream extends Iterable, it is not a general-purpose Iterable as it supports only a single Iterator; invoking the iterator method to obtain a second or subsequent iterator throws IllegalStateException.

So the behaviour you see is to be expected. You should collect all your files to a single list. Something along these lines:

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

Note that this issue about the IllegalStateException is rather distinct from the original question you asked. So it would be better off in a separate question. Remember that SO is not a forum. So please stick to one issue per question.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...