Java库为glob或类似Ant的模式返回List <File>"*foo/**/*.txt"?

Ond*_*žka 10 java design-patterns directory-walk

我正在寻找一个lib,它将提供一个方法,它会给我一个匹配给定Ant模式的文件列表.

因为*foo/**/*.txt我得到了

foo/x.txt
foo/bar/baz/.txt
myfoo/baz/boo/bar.txt
Run Code Online (Sandbox Code Playgroud)

我知道DirWalker可以实现这一点

PathMatcher mat = FileSystems.getDefault().getPathMatcher("glob:" + filesPattern);
Run Code Online (Sandbox Code Playgroud)

,但我宁愿维护一些lib.我希望Commons IO拥有它,但没有.

更新:我很高兴重用Ant的代码,但更喜欢小于整个Ant的东西.

Ond*_*žka 3

所以为了速度我牺牲了几MB的应用程序大小并最终使用了Ant 。DirectoryScanner

另外,还有 Spring 的PathMatchingResourcePatternResolver

//files = new PatternDirWalker( filesPattern ).list( baseDir );
files = new DirScanner( filesPattern ).list( baseDir );


public class DirScanner {

    private String pattern;

    public DirScanner( String pattern ) {
        this.pattern = pattern;
    }

    public List<File> list( File dirToScan ) throws IOException {

            DirectoryScanner ds = new DirectoryScanner();
            String[] includes = {  this.pattern };
            //String[] excludes = {"modules\\*\\**"};
            ds.setIncludes(includes);
            //ds.setExcludes(excludes);
            ds.setBasedir( dirToScan );
            //ds.setCaseSensitive(true);
            ds.scan();

            String[] matches = ds.getIncludedFiles();
            List<File> files = new ArrayList(matches.length);
            for (int i = 0; i < matches.length; i++) {
                files.add( new File(matches[i]) );
            }
            return files;
    }

}// class
Run Code Online (Sandbox Code Playgroud)

这是我开始编码的实现,尚未完成,只是如果有人想完成它。这个想法是它会保留一堆模式,遍历目录树并将内容与实际堆栈深度以及其余部分进行比较,以防**.

但我求助于PathMatcherAnt 的实现。

public class PatternDirWalker {
    //private static final Logger log = LoggerFactory.getLogger( PatternDirWalker.class );

    private String pattern;
    private List segments;
    private PathMatcher mat;

    public PatternDirWalker( String pattern ) {
        this.pattern = pattern;
        this.segments = parseSegments(pattern);
        this.mat = FileSystems.getDefault().getPathMatcher("glob:" + pattern);
    }

    public List<File> list( File dirToScan ) throws IOException{

        return new DirectoryWalker() {
            List<File> files = new LinkedList();

            @Override protected void handleFile( File file, int depth, Collection results ) throws IOException {
                if( PatternDirWalker.this.mat.matches( file.toPath()) )
                    results.add( file );
            }

            public List<File> findMatchingFiles( File dirToWalk ) throws IOException {
                this.walk( dirToWalk, this.files );
                return this.files;
            }
        }.findMatchingFiles( dirToScan );

    }// list()

    private List<Segment> parseSegments( String pattern ) {
        String[] parts = StringUtils.split("/", pattern);
        List<Segment> segs = new ArrayList(parts.length);
        for( String part : parts ) {
            Segment seg = new Segment(part);
            segs.add( seg );
        }
        return segs;
    }

    class Segment {
        public final String pat;  // TODO: Tokenize
        private Segment( String pat ) {
            this.pat = pat;
        }
    }

}// class
Run Code Online (Sandbox Code Playgroud)