使用Java识别文件扩展名可通过
lastIndexOf('.')
定位最后一个点位置,再用substring
截取其后内容,注意处理无点号或点号在末尾的情况,示例代码:,“java,String fileName = "example.txt";,int dotIndex = fileName.lastIndexOf('.');,String ext = (dotIndex > 0 && dotIndex < fileName.length() - 1) , ? fileName.substring(dotIndex + 1) , : "";,
``核心方法及代码实现
使用 String
类方法(纯Java,无依赖)
通过截取文件名最后一个点号()后的字符串获取扩展名,适合简单场景:
public static String getFileExtension(String fileName) { if (fileName == null || fileName.lastIndexOf(".") == -1) { return ""; // 无扩展名或文件名无效 } return fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase(); // 转换为小写统一格式 } // 示例调用 String fileName = "document.pdf"; String extension = getFileExtension(fileName); // 返回 "pdf"
注意点:
- 处理非法路径:如
."txt"
或路径中包含点号(如../file.name.txt
)时仍能正确识别。 - 大小写转换:扩展名统一为小写,避免系统差异(如
.JPG
和.jpg
)。
使用 java.nio.file.Path
(Java 7+ NIO)
通过 Path
对象解析文件名,更规范且避免路径干扰:
import java.nio.file.Path; import java.nio.file.Paths; public static String getExtensionByPath(Path filePath) { String fileName = filePath.getFileName().toString(); // 获取纯文件名 int dotIndex = fileName.lastIndexOf('.'); return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1).toLowerCase(); } // 示例调用 Path path = Paths.get("/user/docs/report.docx"); String extension = getExtensionByPath(path); // 返回 "docx"
使用 FilenameUtils
(Apache Commons IO库)
依赖 commons-io
库,提供健壮的跨平台处理:
-
添加Maven依赖:
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.11.0</version> </dependency>
-
代码实现:
import org.apache.commons.io.FilenameUtils; public static String getExtensionWithCommons(String fileName) { return FilenameUtils.getExtension(fileName).toLowerCase(); } // 示例调用 String fullPath = "C:/data/image.PNG"; String ext = getExtensionWithCommons(fullPath); // 返回 "png"
优势:
- 自动处理
null
和非法路径。 - 兼容Windows/Unix路径格式(如
C:file.txt
或/tmp/file
)。
使用 Files.probeContentType
(Java 7+ NIO.2)非文件名)探测MIME类型,更安全但性能较低:
import java.nio.file.Files; import java.nio.file.Path; public static String getMimeBasedExtension(Path filePath) throws IOException { String mimeType = Files.probeContentType(filePath); if (mimeType == null) return ""; // 将MIME类型转换为常见扩展名(需自定义映射) return mimeType.split("/")[1]; // "image/jpeg" -> "jpeg" } // 示例调用 Path path = Paths.get("photo.jpg"); String mimeExt = getMimeBasedExtension(path); // 返回 "jpeg"
局限性:
- 依赖操作系统文件类型检测,Linux需安装
file
命令。 - 不适用于未存储到磁盘的文件(如网络流)。
关键场景处理
- 无扩展名文件:
所有方法均返回空字符串 ,调用方需做空值判断。 - 点号干扰路径:
Path.getFileName()
和FilenameUtils
能正确忽略目录中的点号(如/tmp.dir/file
)。 - 安全性校验:
- 结合扩展名白名单(如
Arrays.asList("pdf", "docx")
)防止恶意文件上传。 - 重要操作(如执行文件)前,务必用
Files.probeContentType
二次验证。
- 结合扩展名白名单(如
最佳实践推荐
场景 | 推荐方法 | 原因 |
---|---|---|
简单文件名处理 | String.lastIndexOf() |
无依赖、轻量级 |
复杂路径或跨平台 | FilenameUtils.getExtension() |
自动处理路径分隔符和边界条件 |
安全敏感操作(如上传) | Files.probeContentType() + 扩展名白名单 |
避免文件名欺骗,验证实际内容类型 |
- 基础场景:优先使用
String.lastIndexOf(".")
或Path
对象,简洁高效。 - 企业级应用:引入Apache Commons IO的
FilenameUtils
,提升代码健壮性。 - 高安全需求:结合
Files.probeContentType
和扩展名白名单双重验证。 - 避免方法:废弃的
javax.activation.MimetypesFileTypeMap
(Java EE移除)。
引用说明:
本文代码基于Java 17 LTS和Apache Commons IO 2.11.0编写,Apache Commons IO文档参考:commons.apache.org,NIO.2 API详见Oracle官方文档:Files (Java SE 17)。
原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/32870.html