lastIndexOf('.')
定位最后一个点,然后截取其后字符串,需处理无扩展名或点位于末尾的情况,确保准确提取扩展名部分。方法1:使用 String.substring()
和 lastIndexOf()
(原生Java)
原理:通过截取最后一个之后的字符串获取扩展名。
代码示例:
public static String getFileExtension(String fileName) { if (fileName == null || fileName.lastIndexOf(".") == -1) { return ""; // 无扩展名或文件名无效 } return fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase(); } // 调用示例 String fileName = "report.pdf"; String extension = getFileExtension(fileName); // 返回 "pdf"
优点:无需外部依赖,执行效率高。
缺点:
- 无法处理
.tar.gz
等多级扩展名。 - 文件名含特殊路径时(如
../file.txt
)可能出错,需先提取纯文件名。
方法2:使用 java.nio.file.Path
(Java 7+ 推荐)
原理:通过NIO的Path
对象解析文件名和扩展名,避免路径干扰。
代码示例:
import java.nio.file.Paths; import java.nio.file.Path; public static String getExtensionByNio(String filePath) { Path path = Paths.get(filePath); String fileName = path.getFileName().toString(); // 提取纯文件名 int dotIndex = fileName.lastIndexOf("."); return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1).toLowerCase(); } // 调用示例 String path = "/user/docs/archive.zip"; String ext = getExtensionByNio(path); // 返回 "zip"
优点:自动处理路径分隔符,兼容不同操作系统。
缺点:仍无法解决多级扩展名问题。
方法3:使用 Apache Commons IO 库
原理:通过FilenameUtils.getExtension()
方法直接获取扩展名,简化逻辑。
步骤:
-
添加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 getExtensionByCommons(String fileName) { return FilenameUtils.getExtension(fileName).toLowerCase(); } // 调用示例 String fileName = "image.JPEG"; String ext = getExtensionByCommons(fileName); // 返回 "jpeg"
优点:
- 自动处理路径和大小写(如
.JPEG
→jpeg
)。 - 支持复杂文件名(如
C:dirfile.name.with.dots.txt
)。
缺点:需引入第三方库。
关键安全注意事项
- 扩展名不可信:
用户可能伪造扩展名(如将恶意脚本重命名为image.jpg.exe
),仅依赖扩展名会引发安全风险。 - 解决方案:
- 校验文件内容:通过
Files.probeContentType()
(Java 7+)检测MIME类型:Path path = Paths.get("user_file.tmp"); String mimeType = Files.probeContentType(path); // 返回 "image/jpeg"
- 结合扩展名和内容:双重验证确保文件真实类型。
- 校验文件内容:通过
总结建议
场景 | 推荐方法 |
---|---|
简单项目(无外部依赖) | String.substring() + 路径清洗 |
Java 7+ 项目 | java.nio.file.Path |
复杂路径/企业级应用 | Apache Commons IO |
高安全性要求 | 扩展名 + MIME类型双重校验 |
最佳实践:
- 始终将扩展名转换为小写(
.toLowerCase()
)避免大小写敏感问题。- 对上传文件使用白名单机制(如只允许
.pdf, .jpg
)。- 敏感操作(如执行文件)必须校验内容而非仅依赖扩展名。
引用说明:
- Apache Commons IO文档:https://commons.apache.org/proper/commons-io/
- Java NIO
Path
类官方指南:Oracle Java Docs - 文件类型安全验证参考:OWASP File Upload Cheat Sheet
原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/32902.html