java获取文件扩展名的误区

摘要: 获取文件扩展名,在开发中很常见的问题,而且百度一下,网上很多方法,但很多是不健壮的代码片段, 没有考虑到很多情况,比如 tar.gz 应该是一个完整的扩展名,而不应该是gz, 另外还有在linux下很多文件是没有扩展名的,但文件夹中还有.这个特殊符号的情况。所以有了这些考虑,记录下获取文件扩展名的正确方式.

获取文件扩展名,在开发中很常见的问题,而且百度一下,网上很多方法,但很多是不健壮的代码片段。比如如下的例子

/**
 * 这种方法有很明显的BUG, 如果文件没有扩展名,并且路径中含有 ".",那么会出问题
 * @param filePath
 * @return
 */
public static String getExtendNormal(String filePath) {
    String extension = "";
    int index = filePath.lastIndexOf('.');
    if (index > 0) {
        extension = filePath.substring(index + 1);
    }
    return extension;
}

这就很明细没有考虑到路径中有 . 号,并且没有扩展名的情况,在Linux环境下,很多文件是不需要扩展名的,而且路径中有 . 号也常见, 比如下面的测试:

public static void main(String[] args) {
    String[] pathExamples = {"c:\\abc\\222.zip", "c:\\abc.def\\ccc", "c:\\abc\\abc.tar.gz", "/home/yihaomen/abc.def/afile"};
    for (String pathExample : pathExamples) {
        String s = getExtendNormal(pathExample);
        System.out.println(s);
    }
}

输出的是:

zip
def\ccc
gz
def/afile

很明显这是错误的结果。

加强版获取文件扩展名方法

/**
 * 支持文件名中间有. 号并且没有扩展名的情况.
 * @param filePath
 * @return
 */
public static String getExtendImprove(String filePath) {
    String extension = "";
    int indexOfLastExtension = filePath.lastIndexOf(".");

    // 检查windows, linux 最后一个文件分隔符
    int lastSeparatorPosWindows = filePath.lastIndexOf("\\");
    int lastSeparatorPosUnix = filePath.lastIndexOf("/");
    // 最后文件分隔符位置, 取最大值
    int indexOflastSeparator = Math.max(lastSeparatorPosWindows, lastSeparatorPosUnix);

    // 确保.分隔符在文件分隔符之后.
    if (indexOfLastExtension > indexOflastSeparator) {
        extension = filePath.substring(indexOfLastExtension + 1);
    }
    return extension;
}

这种方法,用文件分隔符,去最后一个.号去做判断,然后得到扩展名,这样就会好很多。但这也不是最健壮的方法,比如tar.gz 其实是一个扩展名,而不仅仅是.gz, 这种情况怎么处理,我这里用了hardCode的方法做测试,暂时没想到更好的方法 例子代码如下:

public static String getExtendHardCode(String filePath) {
    String[] hardCodeExtends = {"tar.gz"};
    boolean isHardCode = false;
    String extension = "";

    for(String s: hardCodeExtends) {
        if (filePath.toLowerCase().endsWith(s.toLowerCase())) {
            extension = s;
            isHardCode = true;
            break;
        }
    }
    if (isHardCode) {
        return extension;
    }

    int indexOfLastExtension = filePath.lastIndexOf(".");

    // 检查windows, linux 最后一个文件分隔符
    int lastSeparatorPosWindows = filePath.lastIndexOf("\\");
    int lastSeparatorPosUnix = filePath.lastIndexOf("/");
    // 最后文件分隔符位置, 取最大值
    int indexOflastSeparator = Math.max(lastSeparatorPosWindows, lastSeparatorPosUnix);

    // 确保.分隔符在文件分隔符之后.
    if (indexOfLastExtension > indexOflastSeparator) {
        extension = filePath.substring(indexOfLastExtension + 1);
    }
    return extension;

}

这样,既考虑到特殊的扩展名,也考虑到特殊路径没有扩展名的问题。从自己编码得到文件扩展名的角度来说,这应该是最好的方法了。当然这只是例子,有需要自己还要修改。


当然,其实很多JAR包都已经有现成的工具类了,只要引入包就可以直接调用. 比如 common-io 包。

<dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.7</version>
</dependency>
public static String getExtendByCommonio(String filePath) {
    return FilenameUtils.getExtension(filePath);
}

但这种方法,好像还是不能解决tar.gz这种特殊的扩展名的识别。所以如果要求比较高,还是采用前面介绍的方法.

上一篇: jquery给动态增加的元素绑定事件
下一篇: Centos 7 下安装 Lua 报错 lua.c:80:31: fatal error: readline/readline.h: No such file
 评论 ( What Do You Think )
名称
邮箱
网址
评论
验证
   
 

 


  • 微信公众号

  • 我的微信

站点声明:

1、一号门博客CMS,由Python, MySQL, Nginx, Wsgi 强力驱动

2、部分文章或者资源来源于互联网, 有时候很难判断是否侵权, 若有侵权, 请联系邮箱:summer@yihaomen.com, 同时欢迎大家注册用户,主动发布无版权争议的 文章/资源.

3、鄂ICP备14001754号-3, 鄂公网安备 42280202422812号