3

There are previous questions about checking if a file matches a glob pattern (here is one). However, I would like to get a list of files that match a glob pattern without having to specify the base directory to search. I need to accept both relative and absolute directories (I resolve the relative ones to a specified directory), and it needs to be cross-platform compatible.

Given a string such as "C:/users/foo/", "/user/foo/.txt" or "dir/*.txt", how do I get the list of matching paths?

Community
  • 1
  • 1
Nate Glenn
  • 6,455
  • 8
  • 52
  • 95
  • Why do you not want to specify the base directory? It's easy to do the the ones that have an absolute path and you need to process the ones with a relative path anyways. You might as well supply the base directory for them as well. – Guenther Aug 24 '16 at 04:21
  • But if the path is `../../*.txt`, then it won't be inside of the base directory that I'm resolving from, and I can't resolve it using Path.resolve because `*` is not a legal path character and throws an exception. Also, if it's an absolute path then what base directory should I be specifying? This question was never answered [here](http://stackoverflow.com/questions/25682140/resolve-absolute-paths-with-wildcards-in-java-6). – Nate Glenn Aug 24 '16 at 05:10
  • On top of that I need a programmatic way to ask if the glob pattern is relative in the first place. – Nate Glenn Aug 24 '16 at 05:15

1 Answers1

0

Yes, you'll need a programmatic way to find out if a glob pattern is absolute. This can be done as follows:

    for (String glob : new String[] { "../path/*.txt", "c:/../path/*.txt", "/../path/*.txt" }) {
        System.out.println(glob + ": is " + (new File(glob).isAbsolute() ? "absolute" : "relative"));
    }

On Windows this will output

../path/*.txt: is relative
c:/../path/*.txt: is absolute
/../path/*.txt: is relative

On unix the last is absolute. If you know the glob pattern is relative, prepend the special directory to it. After that you'll have an absolute path for all glob patterns and can use that to specify it for the search.

EDIT 1 As per you comment, you can do the following. But you can also mix and match nio and io. You should know that java.io.File.isAbsolute() only checks the file path FORMAT, not if the file actually exists, to determine if it's in absolute or relative form. It does that in a platform specific manor.

    String baseDir = "c:/BaseDir/";
    for (String glob : new String[] { "../path/*.txt", "c:/../path/*.txt", "/../path/*.txt" }) {
        File file = new File(glob);
        if (!file.isAbsolute()) {
            file = new File(baseDir, glob);
        }
        System.out.println(file.getPath() + ": is " + (file.isAbsolute() ? "absolute" : "relative"));
    }

this will print

c:\BaseDir\..\path\*.txt: is absolute
c:\..\path\*.txt: is absolute
c:\BaseDir\..\path\*.txt: is absolute

you will still have to do the globbing yourself or use any methods described in the post you mentioned (How to find files that match a wildcard string in Java?)

Community
  • 1
  • 1
Guenther
  • 2,035
  • 2
  • 15
  • 20
  • Does java.io have a way to resolve relative paths with arbitrary base directories? It's there in nio... – Nate Glenn Aug 24 '16 at 06:18
  • Not really sure what you are asking. If you have multiple base directories, you can do a loop and prepend each base dir to a relative glob pattern. – Guenther Aug 24 '16 at 06:30
  • I don't mean multiple base directories. I mean that I can do `Path.get('/user/foo').resolve('../relative/dir/file.txt')`. With java.io it seems that relative paths are resolved relative to the current working directory. – Nate Glenn Aug 24 '16 at 07:14