Java:将文件名拆分为基和扩展名

Java:将文件名拆分为基和扩展名,java,file,Java,File,有没有更好的方法来获取文件的basename和扩展名 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); 也许你可以用 要回答您的评论: 我不确定是否可以有多个。在

有没有更好的方法来获取文件的basename和扩展名

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 input = "boo.and.foo";

String[] result = input.split(".");
这将返回一个数组,其中包含:

{ "boo", "and", "foo" }
因此,您将知道数组中的最后一个索引是扩展,所有其他索引都是基索引。

来源:

这种实用程序类别:

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

您还可以使用java正则表达式。String.split()也在内部使用该表达式。参考我知道其他人提到了
String.split
,但是这里有一个变体,它只产生两个令牌(基令牌和扩展令牌):

例如:

"test.cool.awesome.txt".split("\\.(?=[^\\.]+$)");
    String dir = "/foo/bar/bam/boozled"; 
    String[] tokens = dir.split(".+?/(?=[^/]+$)");
    // [ "/foo/bar/bam/" "boozled" ] 
收益率:

["test.cool.awesome", "txt"]
正则表达式告诉Java在任何一个句点上拆分,该句点后跟任意数量的非句点,后跟输入结束。只有一个期间与此定义匹配(即,最后一个期间)

从技术上来说,这种技术被称为


顺便说一句,如果要分割路径并获取完整文件名,包括但不限于点扩展名,请使用带正斜杠的路径

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

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

你的代码怎么了?用一种简洁实用的方法包装就可以了


更重要的是使用什么作为分隔符-第一个或最后一个点。第一个不适用于文件名,如“setup-2.5.1.exe”,最后一个不适用于具有多个扩展名的文件名,如“mybundle.tar.gz”。

旧问题,但我通常使用以下解决方案:

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有内置函数来获取给定文件路径的basename和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());
    }
}
文件扩展名是一个破碎的概念 它没有可靠的功能。例如,考虑这个文件名:

archive.tar.gz
分机号码是多少?DOS用户会更喜欢名称
archive.tgz
。有时您会看到愚蠢的Windows应用程序首先解压缩文件(生成一个
.tar
文件),然后您必须再次打开它才能查看归档内容

在这种情况下,更合理的文件扩展名概念应该是
.tar.gz
。还有
.tar.bz2
.tar.xz
.tar.lz
.tar.lzma
正在使用的文件“扩展名”。但是您如何决定是在最后一个点拆分,还是在倒数第二个点拆分?

改用mime类型。

Java7函数在检测文件类型方面可能比信任文件扩展名更可靠。几乎所有的Unix/Linux世界以及您的网络浏览器和智能手机都已经这样做了。

好吧,是的,但我必须为stringHmm中的最后一个
找到一个正则表达式。我不确定,但您不能直接使用“?或者一个文件名中有1个以上的点?我想这会起作用:
filename.split(“\\”(?=[^\\.]+$)”)
你不能假设只有一个点。亚当:谢谢,我试试。这个答案不正确。因为点没有转义,它将返回一个空数组。我不知道人们为什么害怕依赖;-)@波佐:我同意图书馆是解决这类问题的更好办法。它让其他人为你做维护和思考(这就是为什么我投票支持你的答案!)。这听起来很微不足道,但当我考虑使用一个Apache库时,我的一部分总是犹豫不定,因为我过去在他们的一些东西上经历过“地狱地狱”(我知道,这很琐碎)。@博卓:亚当的100%个权利。这个问题不足以让我有理由再使用另一个库——但如果我已经出于其他原因使用commons io,那么我会使用Filenameutils。@Jason:Regular expressions:the gift of the gift of Contince.:)@波佐-讽刺?真正的问题是,为什么java附带了无数的冗余类,这些类非常接近于使您能够轻松地完成真正想做的事情,但令人沮丧的是,它们从来没有真正做到过。Python中没有与apachecommons等价的东西,因为Python已经内置了所有有用的东西。C#似乎是一种语言的另一个例子,在这种语言中,你可以专注于自己独特的问题,而不必去想如何重新发明轮子或去获得别人发明的轮子。
basename()
将是一个更好的名称,而不是
filename()
,以防没有扩展名(例如像“/etc/hosts”这样的文件名)这将返回“hosts”作为扩展名(而不是“”。图书馆级的实用程序类应该处理角落案例。它有
getBaseName(..)
getExtension(..)
方法。仅对于扩展名,请参见.java.io.File.getName()返回带有扩展名的名称。我更愿意认为,没有像“扩展名”这样的东西:-)在windows中工作时不起作用,并且字符串“fileName”是“D:\resources\ftp\u upload.csv”你能帮帮我吗?@NIKHILCHAURASIA你需要通过加倍来摆脱反斜杠。例如:“D:\\resources\\ftp\u upload.csv”。这如何回答这个问题?无论是
文件
还是
路径
都不允许我分离扩展名。@andreas.abel让我重复一下:文件扩展名是一个不完整的概念。除了DOS 8+3文件名之外,它们不可靠,也没有很好的定义(请考虑
.tar.gz
.tgz
在unix上非常常见)。使用mime类型。@Anony Mousse好吧,我原则上同意,但我与之交互的所有系统中有99999%使用文件名,而不是mime类型使用
文件的问题在哪里。probeContentType
而不是依赖文件名来获得正确的扩展名?这并不能回答问题。我有一个用例,其中文件名(电影)是一个名称+扩展名。如何使用mime类型提取名称?