Reputation: 10423
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.
Upvotes: 585
Views: 886664
Reputation: 21
I prefer to use Path for manipulation of paths. This is a summary:
import java.io.File;
import java.nio.file.Path;
public class PathProcessing {
public static void main(String[] args) {
// Path
System.out.println("\n--name, ext");
// Path pathToFile = Path.of("/path/to/file/foo.txt"); // an alterrnative
Path pathToFile = Path.of("/mypath", "to", "file", "foo.txt");
System.out.println("pathToFile\t\t" + pathToFile.toString());
System.out.println("getFileName\t\t" + pathToFile.getFileName());
System.out.println("getNameCount\t\t" + pathToFile.getNameCount());
System.out.println("getFileSystem\t\t" + pathToFile.getFileSystem());
System.out.println("getName_0\t\t" + pathToFile.getName(0));
System.out.println("getName_2\t\t" + pathToFile.getName(2));
System.out.println("getName_Last\t\t" + pathToFile.getName(pathToFile.getNameCount() - 1));
System.out.println("getParent\t\t" + pathToFile.getParent());
System.out.println("getRoot\t\t" + pathToFile.getRoot());
System.out.println("getName\t\t" + pathToFile.getName(0));
// name, ext
System.out.println("\n--name, ext");
String sFileNameExt = pathToFile.getFileName().toString();
int lastIndex = sFileNameExt.lastIndexOf('.');
String sExt = sFileNameExt.substring(lastIndex + 1);
String sName = sFileNameExt.substring(0, lastIndex);
System.out.println("sFileNameExt\t\t" + sFileNameExt);
System.out.println("sName\t\t" + sName);
System.out.println("sExt\t\t" + sExt);
// File
System.out.println("\n--file");
File file = pathToFile.toFile();
System.out.println("file\t\t" + file.toString());
}
}
Upvotes: 0
Reputation: 44398
As of Java 20 EA (early-access), there is finally a new method Path#getExtension
that returns the extension as a String
:
Paths.get("/Users/admin/notes.txt").getExtension(); // "txt"
Paths.get("/Users/admin/.gitconfig").getExtension(); // "gitconfig"
Paths.get("/Users/admin/configuration.xml.zip").getExtension(); // "zip"
Paths.get("/Users/admin/file").getExtension(); // null
Upvotes: 11
Reputation: 261
The fluent way:
public static String fileExtension(String fileName) { return Optional.of(fileName.lastIndexOf(".")).filter(i-> i >= 0) .filter(i-> i > fileName.lastIndexOf(File.separator)) .map(fileName::substring).orElse(""); }
Upvotes: 1
Reputation:
private String getExtension(File file)
{
String fileName = file.getName();
String[] ext = fileName.split("\\.");
return ext[ext.length -1];
}
Upvotes: 2
Reputation: 8841
In this case, use FilenameUtils.getExtension from Apache Commons IO
Here is an example of how to use it (you may specify either full path or just file name):
import org.apache.commons.io.FilenameUtils;
// ...
String ext1 = FilenameUtils.getExtension("/path/to/file/foo.txt"); // returns "txt"
String ext2 = FilenameUtils.getExtension("bar.exe"); // returns "exe"
Maven dependency:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
Gradle Groovy DSL
implementation 'commons-io:commons-io:2.6'
Gradle Kotlin DSL
implementation("commons-io:commons-io:2.6")
Others https://search.maven.org/artifact/commons-io/commons-io/2.6/jar
Upvotes: 747
Reputation: 978
If you use Spring framework in your project, then you can use StringUtils
import org.springframework.util.StringUtils;
StringUtils.getFilenameExtension("YourFileName")
Upvotes: 23
Reputation: 632
String path = "/Users/test/test.txt";
String extension = "";
if (path.contains("."))
extension = path.substring(path.lastIndexOf("."));
return ".txt"
if you want only "txt", make path.lastIndexOf(".") + 1
Upvotes: 16
Reputation: 127
This particular question gave me a lot of trouble then i found a very simple solution for this problem which i'm posting here.
file.getName().toLowerCase().endsWith(".txt");
That's it.
Upvotes: 6
Reputation: 17713
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
Upvotes: 88
Reputation: 747
Here is another one-liner for Java 8.
String ext = Arrays.stream(fileName.split("\\.")).reduce((a,b) -> b).orElse(null)
It works as follows:
Upvotes: 10
Reputation: 1443
I like the simplicity of spectre's answer, and linked in one of his comments is a link to another answer that fixes dots in file paths, on another question, made by EboMike.
Without implementing some sort of third party API, I suggest:
private String getFileExtension(File file) {
String name = file.getName().substring(Math.max(file.getName().lastIndexOf('/'),
file.getName().lastIndexOf('\\')) < 0 ? 0 : Math.max(file.getName().lastIndexOf('/'),
file.getName().lastIndexOf('\\')));
int lastIndexOf = name.lastIndexOf(".");
if (lastIndexOf == -1) {
return ""; // empty extension
}
return name.substring(lastIndexOf + 1); // doesn't return "." with extension
}
Something like this may be useful in, say, any of ImageIO's write
methods, where the file format has to be passed in.
Why use a whole third party API when you can DIY?
Upvotes: 0
Reputation: 2354
private String getFileExtension(File file) {
String name = file.getName();
int lastIndexOf = name.lastIndexOf(".");
if (lastIndexOf == -1) {
return ""; // empty extension
}
return name.substring(lastIndexOf);
}
Upvotes: 114
Reputation: 2980
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;
}
Upvotes: 10
Reputation: 738
I found a better way to find extension by mixing all above answers
public static String getFileExtension(String fileLink) {
String extension;
Uri uri = Uri.parse(fileLink);
String scheme = uri.getScheme();
if (scheme != null && scheme.equals(ContentResolver.SCHEME_CONTENT)) {
MimeTypeMap mime = MimeTypeMap.getSingleton();
extension = mime.getExtensionFromMimeType(CoreApp.getInstance().getContentResolver().getType(uri));
} else {
extension = MimeTypeMap.getFileExtensionFromUrl(fileLink);
}
return extension;
}
public static String getMimeType(String fileLink) {
String type = CoreApp.getInstance().getContentResolver().getType(Uri.parse(fileLink));
if (!TextUtils.isEmpty(type)) return type;
MimeTypeMap mime = MimeTypeMap.getSingleton();
return mime.getMimeTypeFromExtension(FileChooserUtil.getFileExtension(fileLink));
}
Upvotes: -1
Reputation: 4649
@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());
}
Upvotes: -1
Reputation: 1
try this.
String[] extension = "adadad.adad.adnandad.jpg".split("\\.(?=[^\\.]+$)"); // ['adadad.adad.adnandad','jpg']
extension[1] // jpg
Upvotes: -1
Reputation: 2621
Without use of any library, you can use the String method split as follows :
String[] splits = fileNames.get(i).split("\\.");
String extension = "";
if(splits.length >= 2)
{
extension = splits[splits.length-1];
}
Upvotes: 1
Reputation: 1076
How about REGEX version:
static final Pattern PATTERN = Pattern.compile("(.*)\\.(.*)");
Matcher m = PATTERN.matcher(path);
if (m.find()) {
System.out.println("File path/name: " + m.group(1));
System.out.println("Extention: " + m.group(2));
}
or with null extension supported:
static final Pattern PATTERN =
Pattern.compile("((.*\\" + File.separator + ")?(.*)(\\.(.*)))|(.*\\" + File.separator + ")?(.*)");
class Separated {
String path, name, ext;
}
Separated parsePath(String path) {
Separated res = new Separated();
Matcher m = PATTERN.matcher(path);
if (m.find()) {
if (m.group(1) != null) {
res.path = m.group(2);
res.name = m.group(3);
res.ext = m.group(5);
} else {
res.path = m.group(6);
res.name = m.group(7);
}
}
return res;
}
Separated sp = parsePath("/root/docs/readme.txt");
System.out.println("path: " + sp.path);
System.out.println("name: " + sp.name);
System.out.println("Extention: " + sp.ext);
result for *nix:
path: /root/docs/
name: readme
Extention: txt
for windows, parsePath("c:\windows\readme.txt"):
path: c:\windows\
name: readme
Extention: txt
Upvotes: 3
Reputation: 156
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();
}
}
}
Upvotes: 2
Reputation: 6385
Getting File Extension from File Name
/**
* The extension separator character.
*/
private static final char EXTENSION_SEPARATOR = '.';
/**
* The Unix separator character.
*/
private static final char UNIX_SEPARATOR = '/';
/**
* The Windows separator character.
*/
private static final char WINDOWS_SEPARATOR = '\\';
/**
* The system separator character.
*/
private static final char SYSTEM_SEPARATOR = File.separatorChar;
/**
* Gets the extension of a filename.
* <p>
* This method returns the textual part of the filename after the last dot.
* There must be no directory separator after the dot.
* <pre>
* foo.txt --> "txt"
* a/b/c.jpg --> "jpg"
* a/b.txt/c --> ""
* a/b/c --> ""
* </pre>
* <p>
* The output will be the same irrespective of the machine that the code is running on.
*
* @param filename the filename to retrieve the extension of.
* @return the extension of the file or an empty string if none exists.
*/
public static String getExtension(String filename) {
if (filename == null) {
return null;
}
int index = indexOfExtension(filename);
if (index == -1) {
return "";
} else {
return filename.substring(index + 1);
}
}
/**
* Returns the index of the last extension separator character, which is a dot.
* <p>
* This method also checks that there is no directory separator after the last dot.
* To do this it uses {@link #indexOfLastSeparator(String)} which will
* handle a file in either Unix or Windows format.
* <p>
* The output will be the same irrespective of the machine that the code is running on.
*
* @param filename the filename to find the last path separator in, null returns -1
* @return the index of the last separator character, or -1 if there
* is no such character
*/
public static int indexOfExtension(String filename) {
if (filename == null) {
return -1;
}
int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR);
int lastSeparator = indexOfLastSeparator(filename);
return (lastSeparator > extensionPos ? -1 : extensionPos);
}
/**
* Returns the index of the last directory separator character.
* <p>
* This method will handle a file in either Unix or Windows format.
* The position of the last forward or backslash is returned.
* <p>
* The output will be the same irrespective of the machine that the code is running on.
*
* @param filename the filename to find the last path separator in, null returns -1
* @return the index of the last separator character, or -1 if there
* is no such character
*/
public static int indexOfLastSeparator(String filename) {
if (filename == null) {
return -1;
}
int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR);
int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR);
return Math.max(lastUnixPos, lastWindowsPos);
}
Credits
Upvotes: 1
Reputation: 1266
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"));
}
Upvotes: 19
Reputation: 2980
If on Android, you can use this:
String ext = android.webkit.MimeTypeMap.getFileExtensionFromUrl(file.getName());
Upvotes: 27
Reputation: 19
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;
}
Upvotes: 1
Reputation: 553
String extension = com.google.common.io.Files.getFileExtension("fileName.jpg");
Upvotes: 2
Reputation: 9154
If you plan to use Apache commons-io,and just want to check the file's extension and then do some operation,you can use this,here is a snippet:
if(FilenameUtils.isExtension(file.getName(),"java")) {
someoperation();
}
Upvotes: 8
Reputation: 11228
My dirty and may tiniest using String.replaceAll:
.replaceAll("^.*\\.(.*)$", "$1")
Note that first *
is greedy so it will grab most possible characters as far as it can and then just last dot and file extension will be left.
Upvotes: 12
Reputation: 228
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.
Upvotes: -4
Reputation: 52000
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"
Upvotes: 16
Reputation: 77752
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);
}
Upvotes: 376
Reputation: 1155
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);
}
Upvotes: 0