4 import java.io.IOException;
5 import java.nio.file.FileSystems;
6 import java.nio.file.FileVisitOption;
7 import java.nio.file.FileVisitResult;
8 import java.nio.file.Files;
9 import java.nio.file.Path;
10 import java.nio.file.PathMatcher;
11 import java.nio.file.Paths;
12 import java.nio.file.SimpleFileVisitor;
13 import java.nio.file.attribute.BasicFileAttributes;
14 import java.util.ArrayList;
15 import java.util.EnumSet;
16 import java.util.List;
17 import java.util.stream.Collectors;
19 public class FileUtils
22 * Given string glob pattern (see
23 * https://docs.oracle.com/javase/7/docs/api/java/nio/file/FileSystem.html#getPathMatcher(java.lang.String)
24 * ) return a List of Files that match the pattern.
25 * Note this is a java style glob, not necessarily a bash-style glob, though there are sufficient similarities.
27 public static List<File> getFilesFromGlob(String pattern)
29 List<File> files = new ArrayList<>();
31 * For efficiency of the Files.walkFileTree, let's find the longest path that doesn't need globbing.
32 * We look for the first glob character * { ? and then look for the last File.separator before that.
33 * Then we can reset the path to look at and shorten the globbing pattern.
34 * Relative paths can be used in pattern, which work from the pwd (though these are converted into
35 * full paths in the match).
37 int firstGlobChar = -1;
38 boolean foundGlobChar = false;
39 for (char c : new char[] { '*', '{', '?' })
41 if (pattern.indexOf(c) > -1
42 && (pattern.indexOf(c) < firstGlobChar || !foundGlobChar))
44 firstGlobChar = pattern.indexOf(c);
48 int lastFS = pattern.lastIndexOf(File.separatorChar, firstGlobChar);
51 String pS = pattern.substring(0, lastFS + 1);
52 String rest = pattern.substring(lastFS + 1);
53 Path parentDir = Paths.get(pS).toAbsolutePath();
54 if (parentDir.toFile().exists())
58 String glob = "glob:" + parentDir.toString() + File.separator
60 PathMatcher pm = FileSystems.getDefault().getPathMatcher(glob);
61 int maxDepth = rest.contains("**") ? Integer.MAX_VALUE
63 .filter(ch -> ch == File.separatorChar).count())
65 Files.walkFileTree(parentDir,
66 EnumSet.of(FileVisitOption.FOLLOW_LINKS), maxDepth,
67 new SimpleFileVisitor<Path>()
70 public FileVisitResult visitFile(Path path,
71 BasicFileAttributes attrs) throws IOException
75 files.add(path.toFile());
77 return FileVisitResult.CONTINUE;
81 public FileVisitResult visitFileFailed(Path file,
82 IOException exc) throws IOException
84 return FileVisitResult.CONTINUE;
87 } catch (IOException e)
96 File f = new File(pattern);
106 public static List<String> getFilenamesFromGlob(String pattern)
108 // convert list of Files to list of File.getPath() Strings
109 return getFilesFromGlob(pattern).stream().map(f -> f.getPath())
110 .collect(Collectors.toList());