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

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

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


当前回答

REGEX版本怎么样:

static final Pattern PATTERN = Pattern.compile("(.*)\\.(.*)");

Matcher m = PATTERN.matcher(path);
if (m.find()) {
    System.out.println("File path/name: " + m.group(1));
    System.out.println("Extention: " + m.group(2));
}

或者支持空扩展名:

static final Pattern PATTERN =
    Pattern.compile("((.*\\" + File.separator + ")?(.*)(\\.(.*)))|(.*\\" + File.separator + ")?(.*)");

class Separated {
    String path, name, ext;
}

Separated parsePath(String path) {
    Separated res = new Separated();
    Matcher m = PATTERN.matcher(path);
    if (m.find()) {
        if (m.group(1) != null) {
            res.path = m.group(2);
            res.name = m.group(3);
            res.ext = m.group(5);
        } else {
            res.path = m.group(6);
            res.name = m.group(7);
        }
    }
    return res;
}


Separated sp = parsePath("/root/docs/readme.txt");
System.out.println("path: " + sp.path);
System.out.println("name: " + sp.name);
System.out.println("Extention: " + sp.ext);

*nix的结果: 路径:/root/docs/ 名称:自述 延伸:三种

对于windows, parsePath("c:\windows\readme.txt"): 路径:c: \ windows \ 名称:自述 延伸:三种

其他回答

private String getFileExtension(File file) {
    String name = file.getName();
    int lastIndexOf = name.lastIndexOf(".");
    if (lastIndexOf == -1) {
        return ""; // empty extension
    }
    return name.substring(lastIndexOf);
}

下面是一个正确处理.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立即是垃圾,以便将其放在堆栈而不是堆上。

    private String getExtension(File file)
        {
            String fileName = file.getName();
            String[] ext = fileName.split("\\.");
            return ext[ext.length -1];
        }

试试这个。

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

我喜欢spectre简单的回答,在他的一个评论中有一个链接到另一个由EboMike提出的问题,它修复了文件路径中的点。

在不实现某种第三方API的情况下,我建议:

private String getFileExtension(File file) {

    String name = file.getName().substring(Math.max(file.getName().lastIndexOf('/'),
            file.getName().lastIndexOf('\\')) < 0 ? 0 : Math.max(file.getName().lastIndexOf('/'),
            file.getName().lastIndexOf('\\')));
    int lastIndexOf = name.lastIndexOf(".");
    if (lastIndexOf == -1) {
        return ""; // empty extension
    }
    return name.substring(lastIndexOf + 1); // doesn't return "." with extension
}

类似的东西在ImageIO的任何写入方法中都可能有用,其中必须传入文件格式。

既然可以自己动手,为什么还要使用整个第三方API呢?