如何在没有Java扩展名的情况下获取文件名?

谁能告诉我如何得到没有扩展名的文件名? 例:

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

如果你像我一样,宁愿使用一些库代码,他们可能已经想到了所有的特殊情况,比如如果你在path中传递null或点而不是在文件名中,会发生什么,你可以使用下面的代码:

 import org.apache.commons.io.FilenameUtils; String fileNameWithOutExt = FilenameUtils.removeExtension(fileNameWithExt); 

最简单的方法是使用正则expression式。

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

上述expression式将删除最后一个点,后跟一个或多个字符。 这是一个基本的unit testing。

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

请参阅以下testing程序:

 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.")); } } 

其输出:

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

如果你的项目使用Guava (14.0或更新),你可以使用Files.getNameWithoutExtension()

(本质上与Apache Commons IO中的FilenameUtils.removeExtension()相同,因为最高票数的答案表明,只是想指出Guava也这样做,我个人不想增加对Commons的依赖 – 我觉得它是只是因为这一点遗物。)

这是按照我的喜好统一列表的顺序。

使用Apache的公共

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

使用谷歌Guava(如果你已经使用它)

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

或者使用核心Java

 String fileName = file.getName(); int pos = fileName.lastIndexOf("."); if (pos > 0) { fileName = fileName.substring(0, pos); } 

虽然我是重用库的一个信徒,但是org.apache.commons.io JAR是174KB,对于移动应用程序来说,这个数字是特别大的。

如果您下载源代码并查看它们的FilenameUtils类,则可以看到有很多额外的实用程序,它可以处理Windows和Unixpath,这非常可爱。

但是,如果您只是想要使用一些静态实用程序方法来使用Unix样式path(带有“/”分隔符),您可能会发现下面的代码有用。

removeExtension方法保留path的其余部分以及文件名。 还有一个类似的getExtension

 /** * Remove the file extension from a filename, that may include a path. * * eg /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 "." * * eg /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; } 

以下是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/> * eg 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); } } 

如果你不喜欢导入完整的apache.commons,我已经提取了相同的function:

 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; } } } 

你可以按“”分割。 并在索引0是文件名和1是扩展名,但我会倾向于从Apache.commons-io的FileNameUtils最好的解决scheme,就像它在第一篇文章中提到的。 它不必被删除,但足够的是:

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

尝试下面的代码。 使用核心Java基本function。 它处理String的扩展名,没有扩展名(没有'.'字符)。 多个'.'的情况'.' 也包括在内。

 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); } 

您可以调整它以使用nullstring。

FilenameUtils

 System.out.println(FilenameUtils.indexOfExtension("/etc/.hidden_file")); System.out.println(FilenameUtils.getExtension("/etc/.hidden_file")); out: 5 hidden_file 

indexOfExtension或indexOfDOT?