I am making a javaFX project using data from files in a data directory as input. I want to use each file name as a String variable. I have already loaded the data:
File path = new File("data");
File [] files = path.listFiles();
for (int i = 0; i < files.length; i++){
if (files[i].isFile()){
items.loadData(files[i].toString());
}
The toString is now data/fileName1.csv. I want to save use fileName1 only. I have tried using the split() method in the loadData() method, like this:
fileName= fileName.split("/")[1]; //should trim to fileName1.csv, works
fileName= fileName.split("\.")[0]; //should trim to fileName1, error
The error for the second split() is "invalid escape sequence (valid ones are \b \t \n \f \r \" \' \ )".
I have tried variations to fix this. Is there a better/more efficient way to accomplish this?
Edit: Changed trim to split
You need to escape your backslash. Try \\.
But for operations like this, you should probably use Path functions such as: https://docs.oracle.com/javase/7/docs/api/java/nio/file/Path.html#getFileName()
You could use the following code and get the filename in just one line.
files[i].substring(files[i].indexOf("/") + 1);
You could do the following :
String fileName = "data/fileName1.csv";
String [] arr = fileName.split("(/|\\.)");
fileName = arr[1];
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.
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("\\")+1));
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.
Using FilenameUtils in Apache Commons IO :
String name1 = FilenameUtils.getName("/ab/cd/xyz.txt");
String name2 = FilenameUtils.getName("c:\\ab\\cd\\xyz.txt");
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. (There's even an overload that accepts an entire String as a 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
Since 1.7
Path p = Paths.get("c:\\temp\\1.txt");
String fileName = p.getFileName().toString();
String directory = p.getParent().toString();
you can use path = C:\Hello\AnotherFolder\TheFileName.PDF
String strPath = path.substring(path.lastIndexOf("\\")+1, path.length());
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];
Considere the case that Java is Multiplatform:
int lastPath = fileName.lastIndexOf(File.separator);
if (lastPath!=-1){
fileName = fileName.substring(lastPath+1);
}
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/
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.
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;
}
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);
This answer works for me in c#:
using System.IO;
string fileName = Path.GetFileName("C:\Hello\AnotherFolder\The File Name.PDF");
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.
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
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);
}
private String getFileExtension(File file) {
String name = file.getName();
int lastIndexOf = name.lastIndexOf(".");
if (lastIndexOf == -1) {
return ""; // empty extension
}
return name.substring(lastIndexOf);
}
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
If on Android, you can use this:
String ext = android.webkit.MimeTypeMap.getFileExtensionFromUrl(file.getName());
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"));
}
If you use Spring framework in your project, then you can use StringUtils
import org.springframework.util.StringUtils;
StringUtils.getFilenameExtension("YourFileName")
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
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"
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.
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;
}
Here is another one-liner for Java 8.
String ext = Arrays.stream(fileName.split("\\.")).reduce((a,b) -> b).orElse(null)
It works as follows:
Split the string into an array of strings using "."
Convert the array into a stream
Use reduce to get the last element of the stream, i.e. the file extension
How about (using Java 1.5 RegEx):
String[] split = fullFileName.split("\\.");
String ext = split[split.length - 1];
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();
}
How about JFileChooser? It is not straightforward as you will need to parse its final output...
JFileChooser filechooser = new JFileChooser();
File file = new File("your.txt");
System.out.println("the extension type:"+filechooser.getTypeDescription(file));
which is a MIME type...
OK...I forget that you don't want to know its MIME type.
Interesting code in the following link:
http://download.oracle.com/javase/tutorial/uiswing/components/filechooser.html
/*
* Get the extension of a file.
*/
public static String getExtension(File f) {
String ext = null;
String s = f.getName();
int i = s.lastIndexOf('.');
if (i > 0 && i < s.length() - 1) {
ext = s.substring(i+1).toLowerCase();
}
return ext;
}
Related question:
How do I trim a file extension from a String in Java?
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.
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.
Java 20 EA
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
// Modified from EboMike's answer
String extension = "/path/to/file/foo.txt".substring("/path/to/file/foo.txt".lastIndexOf('.'));
extension should have ".txt" in it when run.
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();
}
}
}
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
String extension = com.google.common.io.Files.getFileExtension("fileName.jpg");
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;
}
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
Copied from Apache FileNameUtils Class - http://grepcode.com/file/repo1.maven.org/maven2/commons-io/commons-io/1.3.2/org/apache/commons/io/FilenameUtils.java#FilenameUtils.getExtension%28java.lang.String%29
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];
}
private String getExtension(File file)
{
String fileName = file.getName();
String[] ext = fileName.split("\\.");
return ext[ext.length -1];
}
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);
}
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?
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("");
}
try this.
String[] extension = "adadad.adad.adnandad.jpg".split("\\.(?=[^\\.]+$)"); // ['adadad.adad.adnandad','jpg']
extension[1] // jpg