How do I get the file extension of a file in Java?


Answers

Do you really need a "parser" for this?

String extension = "";

int i = fileName.lastIndexOf('.');
if (i > 0) {
    extension = fileName.substring(i+1);
}

Assuming that you're dealing with simple Windows-like file names, not something like archive.tar.gz.

Btw, for the case that a directory may have a '.', but the filename itself doesn't (like /path/to.a/file), you can do

String extension = "";

int i = fileName.lastIndexOf('.');
int p = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('\\'));

if (i > p) {
    extension = fileName.substring(i+1);
}
Question

Just to be clear, I'm not looking for the MIME type.

Let's say I have the following input: /path/to/file/foo.txt

I'd like a way to break this input up, specifically into .txt for the extension. Is there any built in way to do this in Java? I would like to avoid writing my own parser.




Java has a built-in way of dealing with this, in the java.nio.file.Files class, that may work for your needs:

File f = new File("/path/to/file/foo.txt");
String ext = Files.probeContentType(f.toPath());
if(ext.equalsIgnoreCase("txt")) do whatever;

Note that this static method uses the specifications found here to retrieve "content type," which can vary.




  @Test
    public void getFileExtension(String fileName){
      String extension = null;
      List<String> list = new ArrayList<>();
      do{
          extension =  FilenameUtils.getExtension(fileName);
          if(extension==null){
              break;
          }
          if(!extension.isEmpty()){
              list.add("."+extension);
          }
          fileName = FilenameUtils.getBaseName(fileName);
      }while (!extension.isEmpty());
      Collections.reverse(list);
      System.out.println(list.toString());
    }



Here's a method that handles .tar.gz properly, even in a path with dots in directory names:

private static final String getExtension(final String filename) {
  if (filename == null) return null;
  final String afterLastSlash = filename.substring(filename.lastIndexOf('/') + 1);
  final int afterLastBackslash = afterLastSlash.lastIndexOf('\\') + 1;
  final int dotIndex = afterLastSlash.indexOf('.', afterLastBackslash);
  return (dotIndex == -1) ? "" : afterLastSlash.substring(dotIndex + 1);
}

afterLastSlash is created to make finding afterLastBackslash quicker since it won't have to search the whole string if there are some slashes in it.

The char[] inside the original String is reused, adding no garbage there, and the JVM will probably notice that afterLastSlash is immediately garbage in order to put it on the stack instead of the heap.




Just a regular-expression based alternative. Not that fast, not that good.

Pattern pattern = Pattern.compile("\\.([^.]*)$");
Matcher matcher = pattern.matcher(fileName);

if (matcher.find()) {
    String ext = matcher.group(1);
}



As is obvious from all the other answers, there's no adequate "built-in" function. This is a safe and simple method.

String getFileExtension(File file) {
    if (file == null) {
        return "";
    }
    String name = file.getName();
    int i = name.lastIndexOf('.');
    String ext = i > 0 ? name.substring(i + 1) : "";
    return ext;
}



This particular question gives me a lot trouble then i found a very simple solution for this problem which i'm posting here.

file.getName().toLowerCase().endsWith(".txt");

That's it.




In order to take into account file names without characters before the dot, you have to use that slight variation of the accepted answer:

String extension = "";

int i = fileName.lastIndexOf('.');
if (i >= 0) {
    extension = fileName.substring(i+1);
}

"file.doc" => "doc"
"file.doc.gz" => "gz"
".doc" => "doc"



This is a tested method

public static String getExtension(String fileName) {
    char ch;
    int len;
    if(fileName==null || 
            (len = fileName.length())==0 || 
            (ch = fileName.charAt(len-1))=='/' || ch=='\\' || //in the case of a directory
             ch=='.' ) //in the case of . or ..
        return "";
    int dotInd = fileName.lastIndexOf('.'),
        sepInd = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('\\'));
    if( dotInd<=sepInd )
        return "";
    else
        return fileName.substring(dotInd+1).toLowerCase();
}

And test case:

@Test
public void testGetExtension() {
    assertEquals("", getExtension("C"));
    assertEquals("ext", getExtension("C.ext"));
    assertEquals("ext", getExtension("A/B/C.ext"));
    assertEquals("", getExtension("A/B/C.ext/"));
    assertEquals("", getExtension("A/B/C.ext/.."));
    assertEquals("bin", getExtension("A/B/C.bin"));
    assertEquals("hidden", getExtension(".hidden"));
    assertEquals("dsstore", getExtension("/user/home/.dsstore"));
    assertEquals("", getExtension(".strange."));
    assertEquals("3", getExtension("1.2.3"));
    assertEquals("exe", getExtension("C:\\Program Files (x86)\\java\\bin\\javaw.exe"));
}



path = "/Users/test/test.txt"

extension = path.substring(path.lastIndexOf("."), path.length());

return ".txt"

if you want only "txt", make path.lastIndexOf(".") + 1




Here I made a small method (however not that secure and doesnt check for many errors), but if it is only you that is programming a general java-program, this is more than enough to find the filetype. This is not working for complex filetypes, but those are normally not used as much.

    public static String getFileType(String path){
       String fileType = null;
       fileType = path.substring(path.indexOf('.',path.lastIndexOf('/'))+1).toUpperCase();
       return fileType;
}



If you use Guava library, you can resort to Files utility class. It has a specific method, getFileExtension(). For instance:

String path = "c:/path/to/file/foo.txt";
String ext = Files.getFileExtension(path);
System.out.println(ext); //prints txt

In addition you may also obtain the filename with a similar function, getNameWithoutExtension():

String filename = Files.getNameWithoutExtension(path);
System.out.println(filename); //prints foo



How about (using Java 1.5 RegEx):

    String[] split = fullFileName.split("\\.");
    String ext = split[split.length - 1];



Here's the version with Optional as a return value (cause you can't be sure the file has an extension)... also sanity checks...

import java.io.File;
import java.util.Optional;

public class GetFileExtensionTool {

    public static Optional<String> getFileExtension(File file) {
        if (file == null) {
            throw new NullPointerException("file argument was null");
        }
        if (!file.isFile()) {
            throw new IllegalArgumentException("getFileExtension(File file)"
                    + " called on File object that wasn't an actual file"
                    + " (perhaps a directory or device?). file had path: "
                    + file.getAbsolutePath());
        }
        String fileName = file.getName();
        int i = fileName.lastIndexOf('.');
        if (i > 0) {
            return Optional.of(fileName.substring(i + 1));
        } else {
            return Optional.empty();
        }
    }
}



Related



Tags

java java   file   io