dap4/d4core/src/main/java/dap4/core/util/DapUtil.java
static public String
    locateFile(String filename, String abspath, boolean wantdir)
    {
        Deque<String> q = new ArrayDeque<String>();
        // clean up the path and filename
        filename = filename.trim().replace('\\', '/');
        abspath = abspath.trim().replace('\\', '/');
        if(filename.charAt(0) == '/') filename = filename.substring(1);
        if(filename.endsWith("/")) filename = filename.substring(0, filename.length() - 1);
        if(abspath.endsWith("/")) abspath = abspath.substring(0, abspath.length() - 1);
        q.addFirst(abspath);  // prime the search queue

        for(; ; ) {  // breadth first search
            String currentpath = q.poll();
            if(currentpath == null) break; // done searching
            File current = new File(currentpath);
            File[] contents = current.listFiles();
            if(contents != null) {
                for(File subfile : contents) {
                    if(!subfile.getName().equals(filename)) continue;
                    if((wantdir && subfile.isDirectory())
                            || (!wantdir && subfile.isFile())) {
                        // Assume this is it
                        return DapUtil.canonicalpath(subfile.getAbsolutePath());
                    }
                }
                for(File subfile : contents) {
                    if(subfile.isDirectory())
                        q.addFirst(currentpath + "/" + subfile.getName());
                }
            }
        }
        return null;
    }
static public String
    locateFile(String filename, String abspath, boolean wantdir)
    {
        Deque<String> q = new ArrayDeque<String>();
        // clean up the path and filename
        filename = filename.trim().replace('\\', '/');
        abspath = abspath.trim().replace('\\', '/');
        if(filename.charAt(0) == '/') filename = filename.substring(1);
        if(filename.endsWith("/")) filename = filename.substring(0, filename.length() - 1);
        if(abspath.endsWith("/")) abspath = abspath.substring(0, abspath.length() - 1);
        q.addFirst(abspath);  // prime the search queue

        for(; ; ) {  // breadth first search
            String currentpath = q.poll();
            if(currentpath == null) break; // done searching
            File current = new File(currentpath);
            File[] contents = current.listFiles();
            if(contents != null) {
                for(File subfile : contents) {
                    if(!subfile.getName().equals(filename)) continue;
                    if((wantdir && subfile.isDirectory())
                            || (!wantdir && subfile.isFile())) {
                        // Assume this is it
                        return DapUtil.canonicalpath(subfile.getAbsolutePath());
                    }
                }
                for(File subfile : contents) {
                    if(subfile.isDirectory())
                        q.addFirst(currentpath + "/" + subfile.getName());
                }
            }
        }
        return null;
    }
Walk the specified subtree dir tree to try to locate file|dir named filename.
Use breadth first search.

@param filename Name of the file|dir to locate
@param abspath  Absolute path from which to start search
@param wantdir  True if we are looking for a directory,
false if we are looking for a file
@return absolute path of the file or null