明确一点,我并不是在寻找MIME类型。

假设我有以下输入:/path/to/file/foo.txt

我想要一种方法来分解这个输入,特别是扩展为.txt。在Java中有任何内置的方法来做到这一点吗?我希望避免编写自己的解析器。


当前回答

下面是返回值为Optional的版本(因为你不能确定文件有扩展名)…还有健全检查…

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

其他回答

如何(使用Java 1.5 RegEx):

    String[] split = fullFileName.split("\\.");
    String ext = split[split.length - 1];

试试这个。

String[] extension = "adadad.adad.adnandad.jpg".split("\\.(?=[^\\.]+$)"); // ['adadad.adad.adnandad','jpg']
extension[1] // jpg

Java 20 EA

从Java 20 EA(早期访问)开始,终于有了一个新方法Path#getExtension,它将扩展名作为字符串返回:

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

下面是一个正确处理.tar.gz的方法,即使是在目录名中有点的路径中:

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是为了更快地查找afterLastBackslash,因为如果字符串中有一些斜杠,它就不必搜索整个字符串。

原始String中的char[]被重用,没有在那里添加垃圾,JVM可能会注意到afterLastSlash立即是垃圾,以便将其放在堆栈而不是堆上。

下面是Java 8的另一个一行程序。

String ext = Arrays.stream(fileName.split("\\.")).reduce((a,b) -> b).orElse(null)

其工作原理如下:

使用"."将字符串拆分为字符串数组。 将数组转换为流 使用reduce获取流的最后一个元素,即文件扩展名