Java如何获取文件扩展名?
- 后端开发
- 2025-06-20
- 4
核心方法及代码实现
使用 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)。
