java获取文件扩展名的误区
By:Roy.LiuLast updated:2021-02-09
获取文件扩展名,在开发中很常见的问题,而且百度一下,网上很多方法,但很多是不健壮的代码片段。比如如下的例子
/** * 这种方法有很明显的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这种特殊的扩展名的识别。所以如果要求比较高,还是采用前面介绍的方法.
From:一号门
Previous:jquery给动态增加的元素绑定事件
COMMENTS