Java获取文件类型的5种方法

Wesley13
• 阅读 676

前言

工作中经常会用到,判断一个文件的文件类型,这里总结一把,一般判断文件类型的原理有2种方式:

  1. 根据文件扩展名判断
  • 优点:速度快,代码简单

  • 缺点:无法判断出真实的文件类型,例如一些伪造的文件或者没有后缀名称的文件

  1. 根据文件流中前几个字符判断
  • 优点:可以判断出真实的文件类型

  • 缺点:速度慢,代码复杂

下面我会针对每个方法,去测试验证,测试文件如下:

  1. test.png: 创建一个正常的png文件,其扩展名为test.png

  2. test.doc: 复制一份上面的test.png文件,修改其文件名称为test.doc

1. 使用Files.probeContentType

Java1.7开始,提供了用于解决MIME类型的方法 Files.probeContentType:

public static void test() throws IOException {         Path path = new File("d:/test.png").toPath();         String mimeType = Files.probeContentType(path);         System.out.println(mimeType);     }

结果

文件

结果

结论

test.png

image/png

✔️

test.doc

application/msword

此方法利用已安装的FileTypeDetector实现来探查MIME类型。它调用每个实现的 probeContentType来解析类型。

但是,其默认实现是特定于操作系统的,并且可能会失败,具体取决于我们使用的操作系统。

结论:根据文件扩展名判断。

2. 使用URLConnection

_URLConnection_提供了几种用于检测文件的MIME类型的API。

2.1 使用getContentType

public void test(){     File file = new File("d:/test.png");     URLConnection connection = file.toURL().openConnection();     String mimeType = connection.getContentType(); }

结果

文件

结果

结论

test.png

image/png

✔️

test.doc

image/png

✔️

结论:根据文件流中前几个字符判断。能够判断真实的文件类型,但是,这种方法的主要缺点是速度非常慢

2.2 使用guessContentTypeFromName

public void test(){     File file = new File("d:/test.png");     String mimeType = URLConnection.guessContentTypeFromName(file.getName()); }

结果

文件

结果

结论

test.png

image/png

✔️

test.doc

null

❌ 具体参考下面的2.4

该方法利用内部的_FileNameMap_来判断MIME类型。

结论:根据文件扩展名判断。

2.3 使用guessContentTypeFromStream

public static void test() throws Exception {         FileInputStream inputFile = new FileInputStream("d:/test.doc");         String mimeType = URLConnection.guessContentTypeFromStream(new BufferedInputStream(inputFile));         System.out.println(mimeType);     }

结果

文件

结果

结论

test.png

image/png

✔️

test.doc

image/png

✔️

结论:根据文件流中前几个字符判断

2.4 使用getFileNameMap

使用_URLConnection_获得MIME类型的更快方法是使用getFileNameMap()方法:

public void test(){     File file = new File("d:/test.png");     FileNameMap fileNameMap = URLConnection.getFileNameMap();     String mimeType = fileNameMap.getContentTypeFor(file.getName()); }

结果

文件

结果

结论

test.png

image/png

✔️

test.doc

null

该方法返回_URLConnection_的所有实例使用的MIME类型表。然后,该表用于解析输入文件类型。

当涉及_URLConnection_时,MIME类型的内置表非常有限。

默认情况下,该类使用content-types.properties文件,其所在目录为JRE_HOME/lib。但是,我们可以通过使用content.types.user.table属性指定用户特定的表来扩展它 :

System.setProperty("content.types.user.table","<path-to-file>");

结论:根据文件扩展名判断。

3. 使用MimeTypesFileTypeMap

该类是Java 6附带的,因此在使用JDK 1.6时非常方便。

public void test() {     File file = new File("product.png");     MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();     String mimeType = fileTypeMap.getContentType(file.getName()); }

结果

文件

结果

结论

test.png

image/png

✔️

test.doc

application/octet-stream

在这里,我们可以将文件名或_File_实例本身作为参数传递给函数。但是,以_File_实例为参数的函数在内部调用重载方法,该方法接受文件名作为参数。

在内部,此方法查找名为mime.types的文件以进行类型解析。请务必注意,该方法以特定顺序搜索文件:

  1. 以编程方式将条目添加到 _MimetypesFileTypeMap_实例

  2. 用户主目录中的 mime.types

  3. <java.home> /lib/mime.types

  4. 名为 _META-INF / mime.types的_资源

  5. 名为 _META-INF / mimetypes.default的_资源(通常仅在 _activation.jar_文件中找到)

但是,如果找不到文件,它将返回_application/octet-stream_作为响应。

结论:根据文件扩展名判断。

4. 使用jmimemagic

jMimeMagic是一个受限制许可的库,我们可以使用它来获取文件的MIME类型。

配置Maven依赖:

<dependency>     <groupId>net.sf.jmimemagic</groupId>     <artifactId>jmimemagic</artifactId>     <version>0.1.5</version> </dependency>

接下来,我们将探讨如何使用该库:

public void test() {         File file = new File("d:/test.doc");         MagicMatch match = Magic.getMagicMatch(file, false);         System.out.println(match.getMimeType()); }

该库可以处理数据流,因此不需要文件存在于文件系统中。

结果

文件

结果

结论

test.png

image/png

✔️

test.doc

image/png

✔️

结论:根据文件流中前几个字符判断

5. 使用Apache Tika

Apache Tika是一个工具集,可检测并从各种文件中提取元数据和文本。它具有丰富而强大的API,并带有[tika-core],我们可以利用它来检测文件的MIME类型。

配置Maven依赖:

<dependency>     <groupId>org.apache.tika</groupId>     <artifactId>tika-core</artifactId>     <version>1.18</version> </dependency>

接下来,我们将使用detect()方法来解析类型:

public void whenUsingTika_thenSuccess() {     File file = new File("d:/test.doc");     Tika tika = new Tika();     String mimeType = tika.detect(file); }

结果

文件

结果

结论

test.png

image/png

✔️

test.doc

image/png

✔️

结论:根据文件流中前几个字符判断

总结

根据判断原理总结分类如下:

判断原理

方式

根据文件扩展名

1.Files.probeContentType
2.URLConnection.guessContentTypeFromName
3.URLConnection.getFileNameMap
4.MimetypesFileTypeMap

根据文件流中前几个字符

1.URLConnection.getContentType
2.URLConnection.guessContentTypeFromStream
3.jmimemagic
4.tika

具体如何选择,依据需求而定

参考:https://www.baeldung.com/java-file-mime-type

Java获取文件类型的5种方法

               往期推荐 
               
              
             
            
           
          
        
   
       
       
       
  
      
      
      
 
     
     
     

    
    
    

[

Java获取文件类型的5种方法

最常见的10种Java异常问题!

](https://www.oschina.net/action/GoToLink?url=http%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NTkwODE4Mw%3D%3D%26mid%3D2247494073%26idx%3D1%26sn%3Dced1802b986a0d1c73bb99c0a971397d%26chksm%3Dfbcf8481ccb80d971848ea289c3390e299d2b3659edb73855961903057d8b16eb48e656112fa%26scene%3D21%23wechat_redirect)

[

Java获取文件类型的5种方法

SpringBoot接口幂等性实现的4种方案!

](https://www.oschina.net/action/GoToLink?url=http%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NTkwODE4Mw%3D%3D%26mid%3D2247493939%26idx%3D1%26sn%3Dd4e9825fc63c23535bccabb35d9d8657%26chksm%3Dfbcf840bccb80d1dd90291c4a0a36934710b3d3491b8ffbd577f898e5cc611a26c0a7daf4681%26scene%3D21%23wechat_redirect)

[

Java获取文件类型的5种方法

对象复制的7种方法,还是Spring的最好用!

](https://www.oschina.net/action/GoToLink?url=http%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU1NTkwODE4Mw%3D%3D%26mid%3D2247493733%26idx%3D1%26sn%3D2a60ff940cc69a8bf8dae184c961f52f%26chksm%3Dfbcf855dccb80c4b1472125fef0e6ff06390c1df3cedc19cc9d510b244675a7bf2b44f04ab54%26scene%3D21%23wechat_redirect)

关注我,每天陪你进步一点点!

Java获取文件类型的5种方法

本文分享自微信公众号 - Java中文社群(javacn666)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
java中比较两个时间的差值
项目背景1.某篇文稿的发布时间是publishDate,例如:2020072118:00:41。2.现要求判断该篇文稿的发布时间是否在近30天之内。publicstaticlongdayDiff(DatecurrentDate,DatepublishDate){LongcurrentTimecurrentDat
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Python使用filetype精确判断文件类型
Python使用filetype精确判断文件类型(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fwww.cda.cn%2Fview%2F25204.html)判断文件类型在开发中非常常见的需求,怎样才能准确的判断文件类型呢?首先大家想到的是文件的后缀,但是非常遗憾的是这种方法
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
4个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这