99

I'd like to check if a Path (introduced in Java 7) ends with a certain extension. I tried the endsWith() method like so:

Path path = Paths.get("foo/bar.java")
if (path.endsWith(".java")){
    //Do stuff
}

However, this doesn't seem to work because path.endsWith(".java") returns false. It seems the endsWith() method only returns true if there is a complete match for everything after the final directory separator (e.g. bar.java), which isn't practical for me.

So how can I check the file extension of a Path?

Thunderforge
  • 19,637
  • 18
  • 83
  • 130
  • http://stackoverflow.com/questions/3571223/how-do-i-get-the-file-extension-of-a-file-in-java – assylias Dec 11 '13 at 22:44
  • 1
    @assylias, that question is for finding the extension from a `String`, not a `Path` (although it would work with `Path.toString()`, but I was hoping for a way that wouldn't require that). – Thunderforge Dec 12 '13 at 00:43
  • The notion of file extension is os dependent so I don't think there is support for it in File or Path. – assylias Dec 12 '13 at 08:05
  • @assylias: Well, that sucks. The notion of file extension is well-defined and used many times in Windows/Linux/MacOs/Android. Even though they might be less important in Linux than in Windows, they are still very much used on desktop and server applications. – Eric Duminil Nov 29 '19 at 13:24

4 Answers4

97

Java NIO's PathMatcher provides FileSystem.getPathMatcher(String syntaxAndPattern):

PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:*.java");

Path filename = ...;
if (matcher.matches(filename.getFileName())) {
    System.out.println(filename);
}

.getFileName() is required when your path contains more than one component.

See the Finding Files tutorial for details.

FliegendeWurst
  • 176
  • 4
  • 9
fan
  • 2,234
  • 1
  • 23
  • 24
  • 15
    I think this is missing an asterisk, the following works for me: `PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:*.java");` – Josh Aug 18 '15 at 13:38
  • 28
    And if you're looking through different directories, you need to use "glob:**.java" – LaGrandMere Aug 27 '15 at 11:22
  • 1
    For me LaGrandMere's comment did the trick. If @Dave Jarvis could merge his advise into the elected answer, I guess that would help beginners in the NIO-API. Under Windoze: If I do want to use `glob:*.java`, then `filename` should not contain any parent-path. If I use a rel/abs path like `glob:c:/users/muchwow/*.java`, it works (note that \\\\ has to be used with backslashes). The pattern `glob:**.java` just searches for everything with *.java in it, regardless of the parent path. – JackLeEmmerdeur Aug 31 '17 at 12:30
  • Throwing a PathMatcher onto this problem is quite an expensive hammer, compared to just checking whether the filename (string) ends with a suffix. – Max Spring Jun 09 '21 at 17:58
  • https://stackoverflow.com/a/36954357/10663941 – The Prototype Dec 15 '22 at 18:58
79

The Path class does not have a notion of "extension", probably because the file system itself does not have it. Which is why you need to check its String representation and see if it ends with the four five character string .java. Note that you need a different comparison than simple endsWith if you want to cover mixed case, such as ".JAVA" and ".Java":

path.toString().toLowerCase().endsWith(".java");
Miserable Variable
  • 28,432
  • 15
  • 72
  • 133
  • This is not good solution because of possible NullPointer. It is better to use some library (e.g. apache IO utils) or PathMatcher as mentioned above. – KHanusova Nov 17 '20 at 09:46
24

Simple solution:

if( path.toString().endsWith(".java") ) //Do something

You have to be carefull, when using the Path.endsWith method. As you stated, the method will return true only if it matches with a subelement of your Path object. For example:

Path p = Paths.get("C:/Users/Public/Mycode/HelloWorld.java");
System.out.println(p.endsWith(".java")); // false
System.out.println(p.endsWith("HelloWorld.java")); // true
Pero122
  • 892
  • 11
  • 25
4

There is no way to do this directly on the Path object itself.

There are two options I can see:

  1. Convert the Path to a File and call endsWith on the String returned by File.getName()
  2. Call toString on the Path and call endsWith on that String.
Mark
  • 28,783
  • 8
  • 63
  • 92