310

String variable contains a file name, C:\Hello\AnotherFolder\The File Name.PDF. How do I only get the file name The File Name.PDF as a String?

I planned to split the string, but that is not the optimal solution.

1

12 Answers 12

352

just use File.getName()

File f = new File("C:\\Hello\\AnotherFolder\\The File Name.PDF");
System.out.println(f.getName());

using String methods:

  File f = new File("C:\\Hello\\AnotherFolder\\The File Name.PDF");  
System.out.println(f.getAbsolutePath().substring(f.getAbsolutePath().lastIndexOf(File.separator)+1));
Sign up to request clarification or add additional context in comments.

2 Comments

Be careful with pathnames with "/" instead of "\"
@golimar, this should remove both Windows and Unix path (without using File class): YourStringPath.replaceAll("^.*[\\/\\\\]", "")
335

Alternative using Path (Java 7+):

Path p = Paths.get("C:\\Hello\\AnotherFolder\\The File Name.PDF");
String file = p.getFileName().toString();

Note that splitting the string on \\ is platform dependent as the file separator might vary. Path#getName takes care of that issue for you.

5 Comments

Has anyone done a performance comparison on the various methods in this question?
@crush I don't think that Paths.get accesses the file system so wouldn't expect the performance to be materially different from a substring/indexOf.
How come it doesn't exist on Android? weird.
Yes, Path copes with the platform dependent problem of slash/backslash, but only if the file path is from the same machine (or platform). Consider this: you upload file from Internet Explorer and it has the path "C:\\Hello\\AnotherFolder\\The File Name.PDF" but your code is working on a Unix/Linux machine then p.getFileName() will return the whole path, not just The File Name.PDF.
Calling toString() is so awkward.
98

Using FilenameUtils in Apache Commons IO :

String name1 = FilenameUtils.getName("/ab/cd/xyz.txt");
String name2 = FilenameUtils.getName("c:\\ab\\cd\\xyz.txt");

3 Comments

I think this one may be the best, because sometimes you may have to process the file path from other platform
Btw anyone wants to get the filename minus extension can use FilenameUtils.getBaseName(filePath)
This is the best solution. It is platform independent.
35

Any file name/path manipulation should go through APIs in the java.nio.file package.

Specifically, the Path class

[...] may be used to locate a file in a file system. It will typically represent a system dependent file path.

A Path represents a path that is hierarchical and composed of a sequence of directory and file name elements separated by a special separator or delimiter. A root component, that identifies a file system hierarchy, may also be present. The name element that is farthest from the root of the directory hierarchy is the name of a file or directory. [...]

You can get an instance of type Path using the Paths factory method, get (or the FileSystems class as described here).

Once you have an appropriate Path instance representing your full path, you can use getFileName

Returns the name of the file or directory denoted by this path as a Path object. The file name is the farthest element from the root in the directory hierarchy.

For example,

String fullPathStr = "C:\Hello\AnotherFolder\The File Name.PDF";
Path fullPath = Paths.get(fullPathStr);
Path fileName = fullPath.getFileName();

Note: This all assumes you're running in a Windows environment (considering your file path). If not, you'll need to use a FileSystemProvider that supports Windows path naming.


Alternatively, with only string manipulation, and considering the String you're asking about is

C:\Hello\AnotherFolder\The File Name.PDF

we need to extract everything after the last separator, ie. \. That is what we are interested in.

You can do

String fullPath = "C:\\Hello\\AnotherFolder\\The File Name.PDF";
int index = fullPath.lastIndexOf("\\");
String fileName = fullPath.substring(index + 1);

This will retrieve the index of the last \ in your String and extract everything that comes after it into fileName.

If you have a String with a different separator, adjust the lastIndexOf to use that separator.

I've omitted it in the example above, but if you're unsure where the String comes from or what it might contain, you'll want to validate that the lastIndexOf returns a non-negative value because the Javadoc states it'll return

-1 if there is no such occurrence

3 Comments

Actually -1 return value can be used. Assuming the path is not empty and relative path are possible, If '\\' is not found then index +1 is 0 which is the position of the file name in that case.
by the way, "There's even an overload that accepts an entire String as a separator" -- that is exactly the one being used in posted code (lastIndexOf("\\"))
@user85421 🤷 Dunno what I meant to write back then. Edited, thanks!
31

Since 1.7

    Path p = Paths.get("c:\\temp\\1.txt");
    String fileName = p.getFileName().toString();
    String directory = p.getParent().toString();

Comments

11

The other answers didn't quite work for my specific scenario, where I am reading paths that have originated from an OS different to my current one. To elaborate I am saving email attachments saved from a Windows platform on a Linux server. The filename returned from the JavaMail API is something like 'C:\temp\hello.xls'

The solution I ended up with:

String filenameWithPath = "C:\\temp\\hello.xls";
String[] tokens = filenameWithPath.split("[\\\\|/]");
String filename = tokens[tokens.length - 1];

Comments

10

you can use path = C:\Hello\AnotherFolder\TheFileName.PDF

String strPath = path.substring(path.lastIndexOf("\\")+1, path.length());

5 Comments

You should use \\ instead of \
You should not use any of those as it is platform dependent. / on unix and \`(AND THERE IS A BUG IN THE MARKDOWN PARSER HERE) on windows. You can't know. Use another solution like File` or Paths.
Is File.separator also platform dependent? Or would this work... String strPath = path.substring(path.lastIndexOf(File.separator)+1, path.length());
File.separator & File.separatorChar are both "/" on UNIX/Linux/macOS version of JDK, and both "\" on Windows version.
File.separator won't always work here because in Windows a filename can be separated by either "/" or "\\".
4

getFileName() method of java.nio.file.Path used to return the name of the file or directory pointed by this path object.

Path getFileName()

For reference:

https://www.geeksforgeeks.org/path-getfilename-method-in-java-with-examples/

Comments

3

Considere the case that Java is Multiplatform:

int lastPath = fileName.lastIndexOf(File.separator);
if (lastPath!=-1){
    fileName = fileName.substring(lastPath+1);
}

Comments

0

A method without any dependency and takes care of .. , . and duplicate separators.

public static String getFileName(String filePath) {
    if( filePath==null || filePath.length()==0 )
        return "";
    filePath = filePath.replaceAll("[/\\\\]+", "/");
    int len = filePath.length(),
        upCount = 0;
    while( len>0 ) {
        //remove trailing separator
        if( filePath.charAt(len-1)=='/' ) {
            len--;
            if( len==0 )
                return "";
        }
        int lastInd = filePath.lastIndexOf('/', len-1);
        String fileName = filePath.substring(lastInd+1, len);
        if( fileName.equals(".") ) {
            len--;
        }
        else if( fileName.equals("..") ) {
            len -= 2;
            upCount++;
        }
        else {
            if( upCount==0 )
                return fileName;
            upCount--;
            len -= fileName.length();
        }
    }
    return "";
}

Test case:

@Test
public void testGetFileName() {
    assertEquals("", getFileName("/"));
    assertEquals("", getFileName("////"));
    assertEquals("", getFileName("//C//.//../"));
    assertEquals("", getFileName("C//.//../"));
    assertEquals("C", getFileName("C"));
    assertEquals("C", getFileName("/C"));
    assertEquals("C", getFileName("/C/"));
    assertEquals("C", getFileName("//C//"));
    assertEquals("C", getFileName("/A/B/C/"));
    assertEquals("C", getFileName("/A/B/C"));
    assertEquals("C", getFileName("/C/./B/../"));
    assertEquals("C", getFileName("//C//./B//..///"));
    assertEquals("user", getFileName("/user/java/.."));
    assertEquals("C:", getFileName("C:"));
    assertEquals("C:", getFileName("/C:"));
    assertEquals("java", getFileName("C:\\Program Files (x86)\\java\\bin\\.."));
    assertEquals("C.ext", getFileName("/A/B/C.ext"));
    assertEquals("C.ext", getFileName("C.ext"));
}

Maybe getFileName is a bit confusing, because it returns directory names also. It returns the name of file or last directory in a path.

Comments

-1

extract file name using java regex *.

public String extractFileName(String fullPathFile){
        try {
            Pattern regex = Pattern.compile("([^\\\\/:*?\"<>|\r\n]+$)");
            Matcher regexMatcher = regex.matcher(fullPathFile);
            if (regexMatcher.find()){
                return regexMatcher.group(1);
            }
        } catch (PatternSyntaxException ex) {
            LOG.info("extractFileName::pattern problem <"+fullPathFile+">",ex);
        }
        return fullPathFile;
    }

Comments

-1

You can use FileInfo object to get all information of your file.

    FileInfo f = new FileInfo(@"C:\Hello\AnotherFolder\The File Name.PDF");
    MessageBox.Show(f.Name);
    MessageBox.Show(f.FullName);
    MessageBox.Show(f.Extension );
    MessageBox.Show(f.DirectoryName);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.