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

Jas*_*n S 78 java file

是否有更好的方法来获取文件基名和扩展名

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);
Run Code Online (Sandbox Code Playgroud)

Ada*_*ter 152

我知道其他人已经提到过String.split,但是这里有一个只产生两个令牌(基数和扩展名)的变体:

String[] tokens = fileName.split("\\.(?=[^\\.]+$)");
Run Code Online (Sandbox Code Playgroud)

例如:

"test.cool.awesome.txt".split("\\.(?=[^\\.]+$)");
Run Code Online (Sandbox Code Playgroud)

产量:

["test.cool.awesome", "txt"]
Run Code Online (Sandbox Code Playgroud)

正则表达式告诉Java在任何时段之后拆分,后跟任意数量的非句点,然后是输入的结束.只有一个句点与此定义匹配(即最后一个句点).

技术上来讲,这种技术被称为零宽度正向前瞻.


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

    String[] tokens = dir.split(".+?/(?=[^/]+$)");
Run Code Online (Sandbox Code Playgroud)

例如:

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

  • @Bozho:我同意库是解决此类问题的更好解决方案.它让其他人为你做维护和思考(这就是为什么我投票给你的答案!).这可能听起来微不足道,但是当我考虑加入一个Apache库时,我总有一些犹豫不决,因为我过去曾经遇到过"JAR地狱"的一些东西(我知道,这很简单). (3认同)
  • @Bozho:Adam 100%正确.这个问题不足以保证我接受另一个库 - 但如果我因其他原因已经使用了commons-io,那么我会使用Filenameutils. (3认同)
  • @Bozho - 讽刺?真正的问题是为什么java会带来无穷无尽的冗余类,这些冗余类非常接近于让你很容易做你真正想要做的事情,但后来实际上从未真正做到这一点.在Python中没有与Apache-Commons相同的东西,因为Python只是拥有你想要内置的所有有用的东西.C#似乎是一种语言的另一个例子,你可以专注于你的独特问题,而不必弄清楚如何重新发明轮子或获得别人发明的轮子. (3认同)
  • 我不知道为什么人们害怕依赖;-) (2认同)

小智 76

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

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" !)
Run Code Online (Sandbox Code Playgroud)

  • @NIKHILCHAURASIA你需要通过加倍来逃避反斜杠.喜欢:"D:\\ resources \\ ftp_upload.csv". (2认同)

Erh*_*mir 8

来源: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);
  }
}
Run Code Online (Sandbox Code Playgroud)

用法:

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());
  }
}
Run Code Online (Sandbox Code Playgroud)

  • `basename()`是一个更好的名字,而不是`filename()` (4认同)

Ano*_*sse 7

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

archive.tar.gz
Run Code Online (Sandbox Code Playgroud)

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

archive.tar.gz
Run Code Online (Sandbox Code Playgroud)

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

还有存在它没有可靠的功能.考虑例如这个文件名:

archive.tar.gz
Run Code Online (Sandbox Code Playgroud)

什么扩展名?DOS用户会更喜欢这个名字archive.tgz.有时您会看到首先解压缩文件的愚蠢 Windows应用程序(生成.tar文件),然后您必须再次打开它以查看存档内容.

在这种情况下,文件扩展的概念会更合理.tar.gz.也有.tar.bz2,.tar.xz,.tar.lz.tar.lzma在文件中使用"扩展".但是你会如何决定,是分裂在最后一个点还是倒数第二个点?

请改用mime-types.

Java 7函数Files.probeContentType检测文件类型可能比信任文件扩展名更可靠.几乎所有Unix/Linux世界以及Webbrowser和Smartphone都已经这样做了.

  • 这并不能回答问题。我有一个用例,其中文件名(电影)是名称+扩展名。如何使用 mime 类型提取名称? (7认同)
  • 这是如何回答这个问题的?"文件"和"路径"都不允许我拆分扩展名. (5认同)
  • @Anony-Mousse 嗯,我原则上同意,但我与之交互的所有系统中 99,999% 使用文件名,而不是 mime 类型 (3认同)

Igo*_*gor 6

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

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

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

  • java.io.File.getName()返回带扩展名的名称. (4认同)
  • 我更愿意认为没有像"扩展"这样的东西:-) (2认同)