热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java获取文件的真实类型(通过文件魔数判断文件类型)

背景通常情况下,我们取文件的后缀名作为文件的类型即可,但有时为了防止用户随便修改后缀名,就需要获取文件的真实类型。这时候可以通过文件的魔

背景

通常情况下,我们取文件的后缀名作为文件的类型即可,但有时为了防止用户随便修改后缀名,就需要获取文件的真实类型。这时候可以通过文件的魔数来判别。魔数就是文件开头的那几个字节的数据。

代码实现


工具类代码

import java.util.HashMap;
import java.util.Map;/*** @author lixk* @description 魔数工具类*/
public class MagicNumberUtils {/*** 魔数到文件类型的映射集合*/public static final Map<String, String> TYPES &#61; new HashMap<>();static {// 图片&#xff0c;此处只提取前六位作为魔数TYPES.put("FFD8FF", "jpg");TYPES.put("89504E", "png");TYPES.put("474946", "gif");TYPES.put("524946", "webp");}/*** 根据文件的字节数据获取文件类型** &#64;param data 文件字节数组数据* &#64;return*/public static String getFileType(byte[] data) {//提取前六位作为魔数String magicNumberHex &#61; getHex(data, 6);return TYPES.get(magicNumberHex);}/*** 获取16进制表示的魔数** &#64;param data 字节数组形式的文件数据* &#64;param magicNumberLength 魔数长度* &#64;return*/public static String getHex(byte[] data, int magicNumberLength) {//提取文件的魔数StringBuilder magicNumber &#61; new StringBuilder();//一个字节对应魔数的两位int magicNumberByteLength &#61; magicNumberLength / 2;for (int i &#61; 0; i < magicNumberByteLength; i&#43;&#43;) {magicNumber.append(Integer.toHexString(data[i] >> 4 & 0xF));magicNumber.append(Integer.toHexString(data[i] & 0xF));}return magicNumber.toString().toUpperCase();}}

单元测试类

import com.kalikali.userbiz.util.MagicNumberUtils;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;/*** &#64;author lixk* &#64;description 文件魔数测试*/
&#64;SpringBootTest
public class MagicNumberUtilsTests {/*** 读取文件字节数据** &#64;param filePath* &#64;return* &#64;throws IOException*/public static byte[] getFileBytesData(String filePath) throws IOException {InputStream fs &#61; new FileInputStream(filePath);byte[] b &#61; new byte[fs.available()];fs.read(b);return b;}/*** 根据文件魔数获取文件类型*/&#64;Testpublic void getFileType() throws Exception {System.out.println(MagicNumberUtils.getFileType(getFileBytesData("src/test/resources/images/1.jpg")));System.out.println(MagicNumberUtils.getFileType(getFileBytesData("src/test/resources/images/2.jpg")));System.out.println(MagicNumberUtils.getFileType(getFileBytesData("src/test/resources/images/1.png")));System.out.println(MagicNumberUtils.getFileType(getFileBytesData("src/test/resources/images/1.gif")));System.out.println(MagicNumberUtils.getFileType(getFileBytesData("src/test/resources/images/3.gif")));System.out.println(MagicNumberUtils.getFileType(getFileBytesData("src/test/resources/images/1.webp")));}
}

运行结果

在这里插入图片描述
如果需要判断其他类型文件的真实类型&#xff0c;可以自行添加完善 魔数-类型 map.


推荐阅读
  • 本文介绍了如何利用ObjectMapper实现JSON与JavaBean之间的高效转换。ObjectMapper是Jackson库的核心组件,能够便捷地将Java对象序列化为JSON格式,并支持从JSON、XML以及文件等多种数据源反序列化为Java对象。此外,还探讨了在实际应用中如何优化转换性能,以提升系统整体效率。 ... [详细]
  • 本指南从零开始介绍Scala编程语言的基础知识,重点讲解了Scala解释器REPL(读取-求值-打印-循环)的使用方法。REPL是Scala开发中的重要工具,能够帮助初学者快速理解和实践Scala的基本语法和特性。通过详细的示例和练习,读者将能够熟练掌握Scala的基础概念和编程技巧。 ... [详细]
  • 本文探讨了 Java 中 Pair 类的历史与现状。虽然 Java 标准库中没有内置的 Pair 类,但社区和第三方库提供了多种实现方式,如 Apache Commons 的 Pair 类和 JavaFX 的 javafx.util.Pair 类。这些实现为需要处理成对数据的开发者提供了便利。此外,文章还讨论了为何标准库未包含 Pair 类的原因,以及在现代 Java 开发中使用 Pair 类的最佳实践。 ... [详细]
  • 在Android 4.4系统中,通过使用 `Intent` 对象并设置动作 `ACTION_GET_CONTENT` 或 `ACTION_OPEN_DOCUMENT`,可以从相册中选择图片并获取其路径。具体实现时,需要为 `Intent` 添加相应的类别,并处理返回的 Uri 以提取图片的文件路径。此方法适用于需要从用户相册中选择图片的应用场景,能够确保兼容性和用户体验。 ... [详细]
  • 在前文探讨了Spring如何为特定的bean选择合适的通知器后,本文将进一步深入分析Spring AOP框架中代理对象的生成机制。具体而言,我们将详细解析如何通过代理技术将通知器(Advisor)中包含的通知(Advice)应用到目标bean上,以实现切面编程的核心功能。 ... [详细]
  • 分享一款基于Java开发的经典贪吃蛇游戏实现
    本文介绍了一款使用Java语言开发的经典贪吃蛇游戏的实现。游戏主要由两个核心类组成:`GameFrame` 和 `GamePanel`。`GameFrame` 类负责设置游戏窗口的标题、关闭按钮以及是否允许调整窗口大小,并初始化数据模型以支持绘制操作。`GamePanel` 类则负责管理游戏中的蛇和苹果的逻辑与渲染,确保游戏的流畅运行和良好的用户体验。 ... [详细]
  • Java中不同类型的常量池(字符串常量池、Class常量池和运行时常量池)的对比与关联分析
    在研究Java虚拟机的过程中,笔者发现存在多种类型的常量池,包括字符串常量池、Class常量池和运行时常量池。通过查阅CSDN、博客园等相关资料,对这些常量池的特性、用途及其相互关系进行了详细探讨。本文将深入分析这三种常量池的差异与联系,帮助读者更好地理解Java虚拟机的内部机制。 ... [详细]
  • 在Android应用开发中,实现与MySQL数据库的连接是一项重要的技术任务。本文详细介绍了Android连接MySQL数据库的操作流程和技术要点。首先,Android平台提供了SQLiteOpenHelper类作为数据库辅助工具,用于创建或打开数据库。开发者可以通过继承并扩展该类,实现对数据库的初始化和版本管理。此外,文章还探讨了使用第三方库如Retrofit或Volley进行网络请求,以及如何通过JSON格式交换数据,确保与MySQL服务器的高效通信。 ... [详细]
  • 本文深入解析了Java面向对象编程的核心概念及其应用,重点探讨了面向对象的三大特性:封装、继承和多态。封装确保了数据的安全性和代码的可维护性;继承支持代码的重用和扩展;多态则增强了程序的灵活性和可扩展性。通过具体示例,文章详细阐述了这些特性在实际开发中的应用和优势。 ... [详细]
  • Python内置模块详解:正则表达式re模块的应用与解析
    正则表达式是一种强大的文本处理工具,通过特定的字符序列来定义搜索模式。本文详细介绍了Python内置的`re`模块,探讨了其在字符串匹配、验证和提取中的应用。例如,可以通过正则表达式验证电子邮件地址、电话号码、QQ号、密码、URL和IP地址等。此外,文章还深入解析了`re`模块的各种函数和方法,提供了丰富的示例代码,帮助读者更好地理解和使用这一工具。 ... [详细]
  • 技术日志:使用 Ruby 爬虫抓取拉勾网职位数据并生成词云分析报告
    技术日志:使用 Ruby 爬虫抓取拉勾网职位数据并生成词云分析报告 ... [详细]
  • 本文首先介绍了BGP的基本概念和基础知识,详细解析了BGP的不同邻居类型及其作用。接着,文章对BGP的报文格式、状态机以及路由宣告原则进行了深入探讨,包括本地宣告、引入宣告和缺省路由的处理方法。通过这些内容,读者可以全面了解BGP路由协议的核心机制及其在实际网络中的应用。 ... [详细]
  • SQLite数据库CRUD操作实例分析与应用
    本文通过分析和实例演示了SQLite数据库中的CRUD(创建、读取、更新和删除)操作,详细介绍了如何在Java环境中使用Person实体类进行数据库操作。文章首先阐述了SQLite数据库的基本概念及其在移动应用开发中的重要性,然后通过具体的代码示例,逐步展示了如何实现对Person实体类的增删改查功能。此外,还讨论了常见错误及其解决方法,为开发者提供了实用的参考和指导。 ... [详细]
  • 在Android开发中,实现多点触控功能需要使用`OnTouchListener`监听器来捕获触摸事件,并在`onTouch`方法中进行详细的事件处理。为了优化多点触控的交互体验,开发者可以通过识别不同的触摸手势(如缩放、旋转等)并进行相应的逻辑处理。此外,还可以结合`MotionEvent`类提供的方法,如`getPointerCount()`和`getPointerId()`,来精确控制每个触点的行为,从而提升用户操作的流畅性和响应性。 ... [详细]
  • 深入理解 Java 控制结构的全面指南 ... [详细]
author-avatar
Amyb__ing舒
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有