350

Can anyone tell me how to get the filename without the extension? Example:

fileNameWithExt = "test.xml"; fileNameWithOutExt = "test"; 
1

25 Answers 25

539

If you, like me, would rather use some library code where they probably have thought of all special cases, such as what happens if you pass in null or dots in the path but not in the filename, you can use the following:

import org.apache.commons.io.FilenameUtils; String fileNameWithOutExt = FilenameUtils.removeExtension(fileNameWithExt); 
Sign up to request clarification or add additional context in comments.

8 Comments

you can also use FilenameUtils.getBasename to go straight from a path string to a filename-without-extension.
The easiest is of course running maven :-) Otherwise see: commons.apache.org/io
For those who prefer Guava, it can do this too. (These days I don't personally feel very good about adding Apache Commons dependencies, though historically those libraries have been very useful.)
While Guava and Commons-IO may offer a little extra, you'd be surprised how many convenience methods are already included in JDK 7 with java.nio.file.Files and Path -- such as resolving base directories, one-line copying/moving files, getting only the file name etc.
@Lan Durkan currently FilenameUtils.getBaseName with capital N
|
193

The easiest way is to use a regular expression.

fileNameWithOutExt = "test.xml".replaceFirst("[.][^.]+$", ""); 

The above expression will remove the last dot followed by one or more characters. Here's a basic unit test.

public void testRegex() { assertEquals("test", "test.xml".replaceFirst("[.][^.]+$", "")); assertEquals("test.2", "test.2.xml".replaceFirst("[.][^.]+$", "")); } 

6 Comments

Regex is not as easy to use as the library solution above. It works, but looking at the code (without having to interpret the REGEX) isn't obvious what it does.
@GustavoLitovsky Android doesn't come bundled with org.apache.commons. As far as I'm aware, this is the only way to do it in Android.
/* the following regex also removes path */ "/the/path/name.extension".replaceAll(".*[\\\\/]|\\.[^\\.]*$","");
I would add slashes to the second character class to ensure that you're not tripped up by a path like "/foo/bar.x/baz"
To not have to worry about paths create File object then getName on it and then use this regex.
|
83

Here is the consolidated list order by my preference.

Using apache commons

import org.apache.commons.io.FilenameUtils; String fileNameWithoutExt = FilenameUtils.getBaseName(fileName); OR String fileNameWithOutExt = FilenameUtils.removeExtension(fileName); 

Using Google Guava (If u already using it)

import com.google.common.io.Files; String fileNameWithOutExt = Files.getNameWithoutExtension(fileName); 

Files.getNameWithoutExtension

Or using Core Java

1)

String fileName = file.getName(); int pos = fileName.lastIndexOf("."); if (pos > 0 && pos < (fileName.length() - 1)) { // If '.' is not the first or last character. fileName = fileName.substring(0, pos); } 
if (fileName.indexOf(".") > 0) { return fileName.substring(0, fileName.lastIndexOf(".")); } else { return fileName; } 
private static final Pattern ext = Pattern.compile("(?<=.)\\.[^.]+$"); public static String getFileNameWithoutExtension(File file) { return ext.matcher(file.getName()).replaceAll(""); } 

Liferay API

import com.liferay.portal.kernel.util.FileUtil; String fileName = FileUtil.stripExtension(file.getName()); 

Comments

59

See the following test program:

public class javatemp { static String stripExtension (String str) { // Handle null case specially. if (str == null) return null; // Get position of last '.'. int pos = str.lastIndexOf("."); // If there wasn't any '.' just return the string as is. if (pos == -1) return str; // Otherwise return the string, up to the dot. return str.substring(0, pos); } public static void main(String[] args) { System.out.println ("test.xml -> " + stripExtension ("test.xml")); System.out.println ("test.2.xml -> " + stripExtension ("test.2.xml")); System.out.println ("test -> " + stripExtension ("test")); System.out.println ("test. -> " + stripExtension ("test.")); } } 

which outputs:

test.xml -> test test.2.xml -> test.2 test -> test test. -> test 

5 Comments

What’s the extension of foo.tar.gz? I can see why .tar.gz would be what you would want.
@tchrist, foo.tar.gz is a gzipped version of foo.tar so you could also argue that gz was the extension. It all comes down to how you define the extension.
what to do with files like .gitignore?
as you know class name in java should never start with small letter !
If that were a rule, the language would enforce it. Since it doesn't, it's a guideline however strongly it's suggested. In any case, that's totally irrelevant to the question and answer.
47

If your project uses Guava (14.0 or newer), you can go with Files.getNameWithoutExtension().

(Essentially the same as FilenameUtils.removeExtension() from Apache Commons IO, as the highest-voted answer suggests. Just wanted to point out Guava does this too. Personally I didn't want to add dependency to Commons—which I feel is a bit of a relic—just because of this.)

2 Comments

actually it is more like FilenameUtils.getBaseName()
actually guava is such an unstable lib that i just avoid using it wherever i can. prefer a stable relic than experiments by googel
10

Below is reference from https://android.googlesource.com/platform/tools/tradefederation/+/master/src/com/android/tradefed/util/FileUtil.java

/** * Gets the base name, without extension, of given file name. * <p/> * e.g. getBaseName("file.txt") will return "file" * * @param fileName * @return the base name */ public static String getBaseName(String fileName) { int index = fileName.lastIndexOf('.'); if (index == -1) { return fileName; } else { return fileName.substring(0, index); } } 

1 Comment

Nice info, but users, be aware for cases like ".htaccess", where this method will return "".
9

If you don't like to import the full apache.commons, I've extracted the same functionality:

public class StringUtils { public static String getBaseName(String filename) { return removeExtension(getName(filename)); } public static int indexOfLastSeparator(String filename) { if(filename == null) { return -1; } else { int lastUnixPos = filename.lastIndexOf(47); int lastWindowsPos = filename.lastIndexOf(92); return Math.max(lastUnixPos, lastWindowsPos); } } public static String getName(String filename) { if(filename == null) { return null; } else { int index = indexOfLastSeparator(filename); return filename.substring(index + 1); } } public static String removeExtension(String filename) { if(filename == null) { return null; } else { int index = indexOfExtension(filename); return index == -1?filename:filename.substring(0, index); } } public static int indexOfExtension(String filename) { if(filename == null) { return -1; } else { int extensionPos = filename.lastIndexOf(46); int lastSeparator = indexOfLastSeparator(filename); return lastSeparator > extensionPos?-1:extensionPos; } } } 

Comments

7

For Kotlin it's now simple as:

val fileNameStr = file.nameWithoutExtension 

Comments

5

While I am a big believer in reusing libraries, the org.apache.commons.io JAR is 174KB, which is noticably large for a mobile app.

If you download the source code and take a look at their FilenameUtils class, you can see there are a lot of extra utilities, and it does cope with Windows and Unix paths, which is all lovely.

However, if you just want a couple of static utility methods for use with Unix style paths (with a "/" separator), you may find the code below useful.

The removeExtension method preserves the rest of the path along with the filename. There is also a similar getExtension.

/** * Remove the file extension from a filename, that may include a path. * * e.g. /path/to/myfile.jpg -> /path/to/myfile */ public static String removeExtension(String filename) { if (filename == null) { return null; } int index = indexOfExtension(filename); if (index == -1) { return filename; } else { return filename.substring(0, index); } } /** * Return the file extension from a filename, including the "." * * e.g. /path/to/myfile.jpg -> .jpg */ public static String getExtension(String filename) { if (filename == null) { return null; } int index = indexOfExtension(filename); if (index == -1) { return filename; } else { return filename.substring(index); } } private static final char EXTENSION_SEPARATOR = '.'; private static final char DIRECTORY_SEPARATOR = '/'; public static int indexOfExtension(String filename) { if (filename == null) { return -1; } // Check that no directory separator appears after the // EXTENSION_SEPARATOR int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR); int lastDirSeparator = filename.lastIndexOf(DIRECTORY_SEPARATOR); if (lastDirSeparator > extensionPos) { LogIt.w(FileSystemUtil.class, "A directory separator appears after the file extension, assuming there is no file extension"); return -1; } return extensionPos; } 

Comments

4

Given the String filename, you can do:

String filename = "test.xml"; filename.substring(0, filename.lastIndexOf(".")); // Output: test filename.split("\\.")[0]; // Output: test 

Comments

3
fileEntry.getName().substring(0, fileEntry.getName().lastIndexOf(".")); 

Comments

2

Simplest way to get name from relative path or full path is using

import org.apache.commons.io.FilenameUtils; FilenameUtils.getBaseName(definitionFilePath)

Comments

2

You can use java split function to split the filename from the extension, if you are sure there is only one dot in the filename which for extension.

File filename = new File('test.txt'); File.getName().split("[.]");

so the split[0] will return "test" and split[1] will return "txt"

1 Comment

What if the file contains multiple '.' in such case this method will give an unexpected results.
1
public static String getFileExtension(String fileName) { if (TextUtils.isEmpty(fileName) || !fileName.contains(".") || fileName.endsWith(".")) return null; return fileName.substring(fileName.lastIndexOf(".") + 1); } public static String getBaseFileName(String fileName) { if (TextUtils.isEmpty(fileName) || !fileName.contains(".") || fileName.endsWith(".")) return null; return fileName.substring(0,fileName.lastIndexOf(".")); } 

Comments

1

Use FilenameUtils.removeExtension from Apache Commons IO

Example:

You can provide full path name or only the file name.

String myString1 = FilenameUtils.removeExtension("helloworld.exe"); // returns "helloworld" String myString2 = FilenameUtils.removeExtension("/home/abc/yey.xls"); // returns "yey" 

Hope this helps ..

1 Comment

That's already in the accepted answer, what's the point of this post?
1

The fluent way:

public static String fileNameWithOutExt (String fileName) { return Optional.of(fileName.lastIndexOf(".")).filter(i-> i >= 0) .filter(i-> i > fileName.lastIndexOf(File.separator)) .map(i-> fileName.substring(0, i)).orElse(fileName); } 

5 Comments

What would you do with "directory.old/filenoext" ?
Thanks, I added an extra filter line.
Well, now you have a problem with "directory.old/file"
Please see this tiny unit test I created. The point is there are tools aready made and reinventing the wheel sometimes can be a hard job: bitbucket.org/horvoje/workspace/snippets/B9xd6r
You're right. I should rename the function to: fileNameWithPathAndWithOutExt. I thought that was wanted.
0

You can split it by "." and on index 0 is file name and on 1 is extension, but I would incline for the best solution with FileNameUtils from apache.commons-io like it was mentioned in the first article. It does not have to be removed, but sufficent is:

String fileName = FilenameUtils.getBaseName("test.xml");

Comments

0

Keeping it simple, use Java's String.replaceAll() method as follows:

String fileNameWithExt = "test.xml"; String fileNameWithoutExt = fileNameWithExt.replaceAll( "^.*?(([^/\\\\\\.]+))\\.[^\\.]+$", "$1" ); 

This also works when fileNameWithExt includes the fully qualified path.

Comments

0

My solution needs the following import.

import java.io.File; 

The following method should return the desired output string:

private static String getFilenameWithoutExtension(File file) throws IOException { String filename = file.getCanonicalPath(); String filenameWithoutExtension; if (filename.contains(".")) filenameWithoutExtension = filename.substring(filename.lastIndexOf(System.getProperty("file.separator"))+1, filename.lastIndexOf('.')); else filenameWithoutExtension = filename.substring(filename.lastIndexOf(System.getProperty("file.separator"))+1); return filenameWithoutExtension; } 

Comments

0

com.google.common.io.Files

Files.getNameWithoutExtension(sourceFile.getName())

can do a job as well

Comments

0

file name only, where full path is also included. No need for external libs, regex...etc

 public class MyClass { public static void main(String args[]) { String file = "some/long/directory/blah.x.y.z.m.xml"; System.out.println(file.substring(file.lastIndexOf("/") + 1, file.lastIndexOf("."))); //outputs blah.x.y.z.m } } 

Comments

0

If your project uses Spring you can use:

import org.springframework.util.StringUtils; // … StringUtils.stripFilenameExtension("/tmp/myFile.txt") // → "/tmp/myFile" 

NB: This method has its limitations when it comes to dotfiles, where it will return /tmp/ for /tmp/.config (getBaseName() from commons-io has the same problem btw).


This Baeldung article proposes a nifty two-liner that claims to work for all cases:

public static String removeFileExtension(String filename, boolean removeAllExtensions) { if (filename == null || filename.isEmpty()) return filename; return filename.replaceAll("(?<!^)[.]" + (removeAllExtensions ? ".*" : "[^.]*$"), ""); } 

Comments

0

Just put following methods in an helper class.

public static String getFilenameWithoutExtension(final File file) { final String filename = file.getName(); final int pointIndex = filename.lastIndexOf('.'); if (pointIndex > 0) { return filename.substring(0, pointIndex); } else { return filename; } } public static String getFilenameWithoutExtension(String filePath) { int charIndex = filePath.lastIndexOf(java.nio.file.FileSystems.getDefault().getSeparator()); if (charIndex > 0) { filePath = filePath.substring(charIndex + 1); } charIndex = filePath.lastIndexOf('.'); if (charIndex > 0) { return filePath.substring(0, charIndex); } else { return filePath; } } 

Comments

0

Still actual

Stripping all single extensions like .txt and double extensions like .min.js / .tar.gz
I have ignored 0-9 numbers from file extension, as not my case, you can add if required:

public static String getFileNameWithoutExtension(String fileName) { if (StringUtils.isBlank(fileName) || fileName.startsWith(".")) { return fileName; } final String file = fileName.trim().replaceFirst("(?i)(?:\\.[A-Za-z]{1,4})?\\.[A-Za-z]{1,5}$", ""); return file.trim(); } 

and test:

@Test public void test_getFileNameWithoutExtension() { assertThat(getFileNameWithoutExtension("file")).isEqualTo("file"); assertThat(getFileNameWithoutExtension("file.txt")).isEqualTo("file"); assertThat(getFileNameWithoutExtension("FILE.TXT")).isEqualTo("FILE"); assertThat(getFileNameWithoutExtension("File.xml")).isEqualTo("File"); assertThat(getFileNameWithoutExtension("file.conf")).isEqualTo("file"); assertThat(getFileNameWithoutExtension("file.exe")).isEqualTo("file"); assertThat(getFileNameWithoutExtension("file.tar")).isEqualTo("file"); assertThat(getFileNameWithoutExtension("file.js.map")).isEqualTo("file"); assertThat(getFileNameWithoutExtension("file.js.bck")).isEqualTo("file"); assertThat(getFileNameWithoutExtension("file.")).isEqualTo("file."); assertThat(getFileNameWithoutExtension("file.tar.gz")).isEqualTo("file"); assertThat(getFileNameWithoutExtension(" file .tar.gz ")).isEqualTo("file"); assertThat(getFileNameWithoutExtension(".file")).isEqualTo(".file"); assertThat(getFileNameWithoutExtension(".file.txt")).isEqualTo(".file.txt"); assertThat(getFileNameWithoutExtension("file.bla")).isEqualTo("file"); assertThat(getFileNameWithoutExtension(" file ")).isEqualTo("file"); assertThat(getFileNameWithoutExtension("file name")).isEqualTo("file name"); assertThat(getFileNameWithoutExtension("file.internal.bla")).isEqualTo("file.internal"); assertThat(getFileNameWithoutExtension("file-21.03.25.txt")).isEqualTo("file-21.03.25"); assertThat(getFileNameWithoutExtension("file-21.03.25.min.js")).isEqualTo("file-21.03.25"); assertThat(getFileNameWithoutExtension("a.b.c.min.js")).isEqualTo("a.b.c"); assertThat(getFileNameWithoutExtension("file-21.03.25")).isEqualTo("file-21.03.25"); assertThat(getFileNameWithoutExtension("file-21.03.25.")).isEqualTo("file-21.03.25."); assertThat(getFileNameWithoutExtension("widget.v1.js")).isEqualTo("widget.v1"); assertThat(getFileNameWithoutExtension("widget.rc2.css")).isEqualTo("widget.rc2"); assertThat(getFileNameWithoutExtension("widget.v1.js1")).isEqualTo("widget.v1.js1"); assertThat(getFileNameWithoutExtension("widget.rc2.css3")).isEqualTo("widget.rc2.css3"); assertThat(getFileNameWithoutExtension(".env")).isEqualTo(".env"); assertThat(getFileNameWithoutExtension(".env.local")).isEqualTo(".env.local"); } 

Comments

-3

Try the code below. Using core Java basic functions. It takes care of Strings with extension, and without extension (without the '.' character). The case of multiple '.' is also covered.

String str = "filename.xml"; if (!str.contains(".")) System.out.println("File Name=" + str); else { str = str.substring(0, str.lastIndexOf(".")); // Because extension is always after the last '.' System.out.println("File Name=" + str); } 

You can adapt it to work with null strings.

6 Comments

It's pretty bad practise to implement this kind of functionality yourself. On the first glance the task seems to be extremely obvious, but in practise you will face a lot of exceptional situations (like there is no . in file name, or file is a backup and has name like document.docx.backup, etc). It's much more reliable to use external library which deals with all this exceptional situations for you.
On the other hand adding to many libraries to your project will make it larger. So simple things like this could be done by yourself.
No way you should do this yourself. This is hard: files with no extension but . in path, ftp paths, windows and unix slashes, symbolic links etc... You will certainly fail and by trying to gain a bit of memory you will ad a lot of unstability. At the minimum copy the sources of established code if licences permit it.
This code looks like the one from Amit Mishra, except for that intimidating 'if (!str.contains("."))'
would fail in the following case "/someFolder/some.other.folder/someFileWithoutExtention". First thing that popped in mind after 2 seconds.. i'm sure I could come up with a ton load of other examples.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.