Java:将文件名分割为一个基础和扩展名

有没有更好的方式来获取文件的基本名称和扩展比类似的东西

File f = ... String name = f.getName(); int dot = name.lastIndexOf('.'); String base = (dot == -1) ? name : name.substring(0, dot); String extension = (dot == -1) ? "" : name.substring(dot+1); 

我知道其他人已经提到了String.split ,但是这里是一个只产生两个标记(base和extension)的变体:

 String[] tokens = fileName.split("\\.(?=[^\\.]+$)"); 

例如:

 "test.cool.awesome.txt".split("\\.(?=[^\\.]+$)"); 

产量:

 ["test.cool.awesome", "txt"] 

正则expression式告诉Java在任何数量的非句点之后的任何句点之后进行分割,然后是input结束。 只有一个时期符合这个定义(即上一个时期)。

技术上来说,这种技术在语义上是所谓的零宽度正视。


顺便说一句,如果你想拆分一个path,并得到完整的文件名,包括但不限于点扩展名,使用正斜杠的path,

  String[] tokens = dir.split(".+?/(?=[^/]+$)"); 

例如:

  String dir = "/foo/bar/bam/boozled"; String[] tokens = dir.split(".+?/(?=[^/]+$)"); // [ "/foo/bar/bam/" "boozled" ] 

老问题,但我通常使用这个解决scheme:

 import org.apache.commons.io.FilenameUtils; String fileName = "/abc/defg/file.txt"; String basename = FilenameUtils.getBaseName(fileName); String extension = FilenameUtils.getExtension(fileName); System.out.println(basename); // file System.out.println(extension); // txt (NOT ".txt" !) 

Java 7以前有一个名为Path的接口来以便携的方式来处理这些事情:

 Path p = FileSystems.getDefault().getPath(nam); p.getParent(); 

如果您更喜欢较旧的API,请使用File类。

 File f = new File(nam); f.getParent(); 

文件扩展名是一个破碎的概念

并没有可靠的function。 考虑例如这个文件名:

 archive.tar.gz 

什么扩展名? DOS用户将首选名称archive.tgz 。 有时你会看到愚蠢的 Windows应用程序首先解压缩文件(产生一个.tar文件),然后你必须再次打开它才能看到存档内容。

在这种情况下,一个更合理的文件扩展.tar.gz.tar.gz 。 还有使用中的.tar.bz2.tar.xz.tar.lz.tar.lzma文件的“扩展名”。 但是, 你将如何决定是否在最后一个点或者倒数第二个点分开?

使用MIMEtypes。

与信任文件扩展名相比,Java 7函数Files.probeContentType可能更可靠地检测文件types。 几乎所有的Unix / Linux世界,以及您的Web浏览器和智能手机已经这样做。

资料来源: http : //www.java2s.com/Code/Java/File-Input-Output/Getextensionpathandfilename.htm

这样的工具类:

 class Filename { private String fullPath; private char pathSeparator, extensionSeparator; public Filename(String str, char sep, char ext) { fullPath = str; pathSeparator = sep; extensionSeparator = ext; } public String extension() { int dot = fullPath.lastIndexOf(extensionSeparator); return fullPath.substring(dot + 1); } public String filename() { // gets filename without extension int dot = fullPath.lastIndexOf(extensionSeparator); int sep = fullPath.lastIndexOf(pathSeparator); return fullPath.substring(sep + 1, dot); } public String path() { int sep = fullPath.lastIndexOf(pathSeparator); return fullPath.substring(0, sep); } } 

用法:

 public class FilenameDemo { public static void main(String[] args) { final String FPATH = "/home/mem/index.html"; Filename myHomePage = new Filename(FPATH, '/', '.'); System.out.println("Extension = " + myHomePage.extension()); System.out.println("Filename = " + myHomePage.filename()); System.out.println("Path = " + myHomePage.path()); } } 

http://docs.oracle.com/javase/6/docs/api/java/io/File.html#getName();

来自http://www.xinotes.org/notes/note/774/

Java具有内置函数来获取给定文件path的基本名称和dirname,但函数名称并不那么自明。

 import java.io.File; public class JavaFileDirNameBaseName { public static void main(String[] args) { File theFile = new File("../foo/bar/baz.txt"); System.out.println("Dirname: " + theFile.getParent()); System.out.println("Basename: " + theFile.getName()); } } 

你的代码有什么问题? 包装在一个整洁的实用工具方法,它很好。

更重要的是用作分隔符 – 第一个还是最后一个点。 第一个对于像“setup-2.5.1.exe”这样的文件名是不好的,最后一个对于带有像“mybundle.tar.gz”这样的多个扩展名的文件名是不好的。

你也可以用java正则expression式。 String.split()也在内部使用expression式。 请参阅http://download.oracle.com/javase/1.4.2/docs/api/java/util/regex/Pattern.html

也许你可以使用String#split

回答你的评论:

我不确定是否可以有多个。 在一个文件名,但无论如何,即使有更多的点,你可以使用拆分。 考虑例如:

 String input = "boo.and.foo"; String[] result = input.split("."); 

这将返回一个数组,其中包含:

 { "boo", "and", "foo" } 

所以你会知道,数组中的最后一个索引是扩展名,其他的都是基址。