在Java中确定文件类型

以编程方式确定文件的类型可能非常棘手,并且已经提出并实现了许多基于内容的文件标识方法。 Java中有几种可用于检测文件类型的实现,其中大多数很大程度上或完全基于文件的扩展名。 这篇文章介绍了Java中最常见的文件类型检测实现。

本文介绍了几种在Java中识别文件类型的方法。 简要描述每种方法,并用代码清单进行说明,然后将其与输出相关联,该输出演示如何根据扩展名键入不同的公用文件。 某些方法是可配置的,但是除非另有说明,否则此处显示的所有示例均使用开箱即用提供的“默认”映射。

关于示例

这篇文章中显示的屏幕快照是针对某些主题文件运行的每个列出的代码片段,这些主题文件是为了测试Java中文件类型检测的不同实现而创建的。 在介绍这些方法并演示每种方法检测到的类型之前,我将列出要测试的文件,它们的名称以及它们的真实名称。

文件
名称
文件
延期
文件
类型
类型匹配
延期公约?
ActualXml.xml XML文件 XML格式
博客文章PDF PDF格式 没有
blogPost.pdf pdf格式 PDF格式
blogPost.gif gif GIF
blogPost.jpg jpg JPEG格式
blogPost.png png PNG
blogPostPDF.txt 文本文件 PDF格式 没有
blogPostPDF.xml XML文件 PDF格式 没有
blogPostPNG.gif gif PNG 没有
blogPostPNG.jpg jpg PNG 没有
ustin.txt 文本文件 文本
ustin.xml XML文件 文本 没有
尘土 文本 没有

Files.probeContentType(Path)[JDK 7]

Java SE 7引入了高度实用的Files类 , 该类的Javadoc简洁地描述了它的用法:“该类专门由对文件,目录或其他类型的文件进行操作的静态方法组成”,以及“在大多数情况下,此处定义的方法”将委派给关联的文件系统提供者以执行文件操作。”

java.nio.file.Files类提供了方法probeContentType(Path),该方法通过使用“已安装的FileTypeDetector实现”来“探测文件的内容类型”(Javadoc还指出,“ Java虚拟机的给定调用”维护系统范围的文件类型检测器列表”)。

/*** Identify file type of file with provided path and name* using JDK 7's Files.probeContentType(Path).** @param fileName Name of file whose type is desired.* @return String representing identified type of file with provided name.*/
public String identifyFileTypeUsingFilesProbeContentType(final String fileName)
{String fileType = "Undetermined";final File file = new File(fileName);try{fileType = Files.probeContentType(file.toPath());}catch (IOException ioException){out.println("ERROR: Unable to determine file type for " + fileName+ " due to exception " + ioException);}return fileType;
}

对先前定义的文件集执行以上基于Files.probeContentType(Path)的方法时,输出将显示,如下一个屏幕快照所示。

filesProbeContentTypeOnFiles

屏幕快照表明我的JVM上Files.probeContentType(Path)的默认行为似乎与文件扩展名紧密相关。 没有扩展名的文件的文件类型显示为“ null”,其他列出的文件类型与文件的扩展名而不是其实际内容匹配。 例如,所有三个名称都以“ dustin”开头的文件实际上都是同一个单句文本文件,但是Files.probeContentType(Path)声明它们都是不同的类型,并且列出的类型与不同的文件扩展名紧密相关。基本上是相同的文本文件。

MimetypesFileTypeMap.getContentType(String)[JDK 6]

Java SE 6引入了 MimetypesFileTypeMap类,以使用“ .mime.types格式”提供“通过文件扩展名进行文件的数据键入”。 该类的Javadoc解释了该类在给定系统中的哪里查找MIME类型文件条目。 我的示例使用JDK 8安装中提供的现成产品。 下一个代码清单演示了javax.activation.MimetypesFileTypeMap用法。

/*** Identify file type of file with provided name using* JDK 6's MimetypesFileTypeMap.** See Javadoc documentation for MimetypesFileTypeMap class* (http://docs.oracle.com/javase/8/docs/api/javax/activation/MimetypesFileTypeMap.html)* for details on how to configure mapping of file types or extensions.*/
public String identifyFileTypeUsingMimetypesFileTypeMap(final String fileName)
{    final MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();return fileTypeMap.getContentType(fileName);
}

下一个屏幕快照展示了针对一组测试文件运行此示例的输出。

mimeTypesFileMapOnFiles

此输出表明MimetypesFileTypeMap方法为多个文件(包括XML文件和不带.txt后缀的文本文件)返回application / octet-stream的MIME类型。 我们还看到,就像前面讨论的方法一样,这种方法在某些情况下使用文件的扩展名来确定文件类型,因此当该文件名与常规扩展名不同时,会错误地报告该文件的实际文件类型。

URLConnection.getContentType()

我将介绍URLConnection中支持文件类型检测的三种方法。 第一个是URLConnection.getContentType() ,该方法“返回content-type标头字段的值”。 下一个代码清单中演示了此实例方法的使用,并且在代码清单后显示了针对通用测试文件运行该代码的输出。

/*** Identify file type of file with provided path and name* using JDK's URLConnection.getContentType().** @param fileName Name of file whose type is desired.* @return Type of file for which name was provided.*/
public String identifyFileTypeUsingUrlConnectionGetContentType(final String fileName)
{String fileType = "Undetermined";try{final URL url = new URL("file://" + fileName);final URLConnection connection = url.openConnection();fileType = connection.getContentType();}catch (MalformedURLException badUrlEx){out.println("ERROR: Bad URL - " + badUrlEx);}catch (IOException ioEx){out.println("Cannot access URLConnection - " + ioEx);}return fileType;
}

urlConnectionContentTypeOnFiles

使用URLConnection.getContentType()的文件检测方法与文件的扩展名(而不是实际的文件类型URLConnection.getContentType()高度相关。 如果没有扩展名,则返回的字符串为“ content / unknown”。

URLConnection.guessContentTypeFromName(String)

我将在这里介绍的URLConnection提供的第二种文件检测方法是其方法guessContentTypeFromName(String) 。 下一个代码清单和相关的输出屏幕快照中演示了此静态方法的使用。

/*** Identify file type of file with provided path and name* using JDK's URLConnection.guessContentTypeFromName(String).** @param fileName Name of file whose type is desired.* @return Type of file for which name was provided.*/
public String identifyFileTypeUsingUrlConnectionGuessContentTypeFromName(final String fileName)
{return URLConnection.guessContentTypeFromName(fileName);
}

urlConnectionGuessContentTypeFromNameOnFiles

URLConnectionguessContentTypeFromName(String)文件检测方法对没有文件扩展名的文件显示为“ null”,否则返回与文件扩展名紧密镜像的文件类型字符串表示形式。 这些结果与前面显示的Files.probeContentType(Path)方法提供的结果非常相似,一个显着的区别是URLConnectionguessContentTypeFromName(String)方法将扩展名为.xml的文件标识为文件类型“ application / xml”而Files.probeContentType(Path)将这些相同的文件类型标识为“ text / xml”。

URLConnection.guessContentTypeFromStream(InputStream)

我介绍的URLConnection为文件类型检测提供的第三种方法是通过类的静态方法guessContentTypeFromStream(InputStream) 。 接下来显示使用此方法的代码清单以及屏幕快照中的相关输出。

/*** Identify file type of file with provided path and name* using JDK's URLConnection.guessContentTypeFromStream(InputStream).** @param fileName Name of file whose type is desired.* @return Type of file for which name was provided.*/
public String identifyFileTypeUsingUrlConnectionGuessContentTypeFromStream(final String fileName)
{String fileType;try{fileType = URLConnection.guessContentTypeFromStream(new FileInputStream(new File(fileName)));}catch (IOException ex){out.println("ERROR: Unable to process file type for " + fileName + " - " + ex);fileType = "null";}return fileType;
}

urlConnectionGuessContentTypeFromInputStreamOnFilesAllNull

所有文件类型均为空! Javadoc似乎对URLConnection.guessContentTypeFromStream(InputStream)方法的InputStream参数进行了解释:“支持标记的输入流。” 事实证明,在我的示例中, FileInputStream的实例不支持标记(它们对markSupported()的调用均返回false )。

阿帕奇·蒂卡(Apache Tika)

到目前为止,本文中涵盖的所有文件检测示例都是JDK提供的方法。 有些第三方库也可用于检测Java中的文件类型。 一个示例是Apache Tika ,它是一种“内容分析工具包”,它“可以从上千种不同的文件类型中检测并提取元数据和文本。” 在本文中,我将研究如何使用Tika的Facade类及其detect(String)方法来检测文件类型。 我展示的三个示例中的实例方法调用相同,但是结果不同,因为Tika Facade类的每个实例都使用不同的Detector实例化。

下代码清单显示了具有不同DetectorTika实例的实例化。

/** Instance of Tika facade class with default configuration. */
private final Tika defaultTika = new Tika();/** Instance of Tika facade class with MimeTypes detector. */
private final Tika mimeTika = new Tika(new MimeTypes());
his is 
/** Instance of Tika facade class with Type detector. */
private final Tika typeTika = new Tika(new TypeDetector());

通过用各自的Detector实例化Tika这三个实例,我们可以在每个实例上为测试文件集调用detect(String)方法。 接下来显示此代码。

/*** Identify file type of file with provided name using* Tika's default configuration.** @param fileName Name of file for which file type is desired.* @return Type of file for which file name was provided.*/
public String identifyFileTypeUsingDefaultTika(final String fileName)
{return defaultTika.detect(fileName);
}/*** Identify file type of file with provided name using* Tika's with a MimeTypes detector.** @param fileName Name of file for which file type is desired.* @return Type of file for which file name was provided.*/
public String identifyFileTypeUsingMimeTypesTika(final String fileName)
{return mimeTika.detect(fileName);
}/*** Identify file type of file with provided name using* Tika's with a Types detector.** @param fileName Name of file for which file type is desired.* @return Type of file for which file name was provided.*/
public String identifyFileTypeUsingTypeDetectorTika(final String fileName)
{return typeTika.detect(fileName);
}

当对前面的示例中使用的同一组文件执行以上三个Tika检测示例时,输出将显示,如下一个屏幕快照所示。

tikaThreeDetectorsFileTypeDetectionOnFiles

从输出中我们可以看到,默认的Tika检测器报告的文件类型类似于本文前面显示的其他一些方法(与文件扩展名紧密相关)。 其他两个演示过的检测器指出,在大多数情况下,文件类型为application / octet-stream。 因为我调用了接受String的detect(-)的重载版本,所以文件类型检测是“基于已知的文件扩展名”。

如果使用重载的detect(File)方法而不是detect(String) ,则标识的文件类型结果将比以前的Tika示例和以前的JDK示例好得多。 实际上,“假”扩展名不会使检测器蒙上阴影,在我的示例中,默认的Tika检测器在识别适当的文件类型方面尤其出色,即使该扩展名不是与该文件类型关联的普通文件类型也是如此。 接下来显示使用Tika.detect(File)的代码和关联的输出。

/*** Identify file type of file with provided name using* Tika's default configuration.** @param fileName Name of file for which file type is desired.* @return Type of file for which file name was provided.*/public String identifyFileTypeUsingDefaultTikaForFile(final String fileName){String fileType;try{final File file = new File(fileName);fileType = defaultTika.detect(file);}catch (IOException ioEx){out.println("Unable to detect type of file " + fileName + " - " + ioEx);fileType = "Unknown";}return fileType;}/*** Identify file type of file with provided name using* Tika's with a MimeTypes detector.** @param fileName Name of file for which file type is desired.* @return Type of file for which file name was provided.*/public String identifyFileTypeUsingMimeTypesTikaForFile(final String fileName){String fileType;try{final File file = new File(fileName);fileType = mimeTika.detect(file);}catch (IOException ioEx){out.println("Unable to detect type of file " + fileName + " - " + ioEx);fileType = "Unknown";}return fileType;}/*** Identify file type of file with provided name using* Tika's with a Types detector.** @param fileName Name of file for which file type is desired.* @return Type of file for which file name was provided.*/public String identifyFileTypeUsingTypeDetectorTikaForFile(final String fileName){String fileType;try{final File file = new File(fileName);fileType = typeTika.detect(file);}catch (IOException ioEx){out.println("Unable to detect type of file " + fileName + " - " + ioEx);fileType = "Unknown";}return fileType;}

tikaThreeDetectorsFileArgFileTypeDetectionOnFiles

注意事项和自定义

文件类型检测并不是一件容易的事。 本文中演示的Java文件检测方法提供了文件检测的基本方法,这些方法通常高度依赖于文件名的扩展名。 如果使用文件检测方法可以识别的常规扩展名来命名文件,则这些方法通常就足够了。 但是,如果使用非常规文件类型扩展名,或者该扩展名用于具有与该扩展名常规相关联的文件之外的其他类型的文件,则这些文件检测方法中的大多数会在没有定制的情况下崩溃。 幸运的是,大多数方法都提供了自定义文件扩展名到文件类型的映射的能力。 在本文显示的示例中,当扩展名不是特定文件类型的常规扩展名时,使用Tika.detect(File)的Tika方法通常是最准确的。

结论

在Java中,有许多机制可用于简单文件类型检测。 这篇文章回顾了一些用于文件检测的标准JDK方法,以及一些使用Tika进行文件检测的示例。

翻译自: https://www.javacodegeeks.com/2015/02/determining-file-types-java.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/360723.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

程序员编程艺术第十一章:最长公共子序列(LCS)问题

程序员编程艺术第十一章:最长公共子序列(LCS)问题 0、前言 程序员编程艺术系列重新开始创作了(前十章,请参考程序员编程艺术第一~十章集锦与总结)。回顾之前的前十章,有些代码是值得商榷的,因当时的代码只顾…

gateway 过滤器执行顺序_Gateway网关源码解析—路由(1.1)之RouteDefinitionLocator一览...

一、概述本文主要对 路由定义定位器 RouteDefinitionLocator 做整体的认识。在 《Spring-Cloud-Gateway 源码解析 —— 网关初始化》 中,我们看到路由相关的组件 RouteDefinitionLocator / RouteLocator 的初始化。涉及到的类比较多,我们用下图重新梳理下…

ERP开发中应用字符串解析实现界面翻译智能化

ERP中要实现界面多语言的功能,则要对各种情况的字符串进行处理并作出翻译。有些字符串的翻译是有规律可行的,遵循相应的模板模式,解析字符串,可以实现机器翻译的效果。 请看帐套数据库表的设计ADCOMP CREATE TABLE dbo.ADCOMP(REC…

参数详解 复制进程_如何优化PostgreSQL逻辑复制

How to Optimize PostgreSQL Logical Replication逻辑复制( Logical Replication )或 Pglogical 是表级别的复制。两者都是基于 WAL 的复制机制,允许在两个实例之间复制指定表的WAL 。这两个看起来让人迷惑,到底有什么区别呢? Logical Replic…

Android Studio使用说明

声明: 本博客文章原创类别的均为个人原创,版权所有。转载请注明出处: http://blog.csdn.net/ml3947,另外本人的个人博客:http://www.wjfxgame.com。 凌晨的Google I/O大会上,宣布了Android Studio,引起了现场开发者的一片欢呼。那么&#x…

有些窗口底部被任务栏挡住了_开始使用 Tint2 吧,一款 Linux 中的开源任务栏

Tint2 是我们在开源工具系列中的第 14 个工具,它将在 2019 年提高你的工作效率,能在任何窗口管理器中提供一致的用户体验。-- Kevin Sonney每年年初似乎都有疯狂的冲动想提高工作效率。新年的决心,渴望开启新的一年,当然&#xff…

从jHiccup开始

写完“如何在生产中检测和诊断慢速代码”一文后,我受到读者的鼓励,尝试从Azul系统尝试jHiccup 。 去年,我参加了jHiccup的创建者Gil Tene的演讲,探讨了测量延迟的正确方法,其中,他向我们介绍了jHiccup。 它…

华为内部面试题库---(6)

1.在SMP体系结构中,中断亲和性是指将一个或者多个中断绑定到特定CPU core上运行,下列说法错误的是:A.每个硬件设备都会在/proc/irq下有个中断号命令的目录来标志中断亲和性B.IRQ#目录下smp_affinity文件,通过设置CPU位掩码&#x…

基元需要走吗?

我目前正在使用JSF作为视图技术,使用JPA作为持久层的企业应用程序。 它可能是支持bean或服务方法中的某种东西,但令我震惊:是否有充分的理由在企业应用程序中使用原语? 当我开始围绕J2SE 1.2使用Java进行编程(或者是J…

输入参数_太实用!输入参数1秒算出功率,这款计算工具又快又准

随着互联网红利的不断加深,到了后期,不断地各种工具开始涌现,方便了很多用户,填补了市场上的很多空白,有生活娱乐类、提高效率类、垂直专业类、系统工具类等等。工业行业作为各行各业的大头,机械化、智能化…

如何编写NetBeans插件

是否想在NetBeans IDE中添加功能或自动执行某些操作? 跟随我们编写您的第一个NetBeans插件。 让我们超越简单的工具栏示例 ,创建一个可以自动更新的插件。 该代码基于NetBeans的WakaTime插件 。 我们的示例插件将仅打印Hello World语句,并在…

Spring Batch教程–最终指南

这是Spring批处理教程,它是Spring框架的一部分。 Spring Batch提供了可重用的功能,这些功能对于处理大量记录至关重要,包括日志记录/跟踪,事务管理,作业处理统计信息,作业重新启动,跳过和资源管…

箱式图 添加异常值平均值_什么是脏数据?怎样用箱形图分析异常值?终于有人讲明白了...

导读:数据质量分析是数据挖掘中数据准备过程的重要一环,是数据预处理的前提,也是数据挖掘分析结论有效性和准确性的基础。没有可信的数据,数据挖掘构建的模型将是空中楼阁。数据质量分析的主要任务是检查原始数据中是否存在脏数据…

窗口程序ImageView(仿QQ图片查看器)

近期一直在学习窗口程序之类的问题,下午正好有机会和大家讨论一下. 程序运行截图: 应用方法: 1、直接把图像文件拖到图标上表现 2、通过命令行方式,示例:ImageView.exe "带全路径的图像文件名称" 3、打开ImageView.exe&…

USACO3.15stamps(dp)

对dp很无奈。。枚举所有可能达到的值 dp[i]表示到达i值所用最少的邮票 1 /*2 ID: shangca23 LANG: C4 TASK: stamps5 */6 #include <iostream>7 #include<cstdio>8 #include<cstring>9 #include<stdlib.h> 10 #include<algorithm> …

基于价值的类

在Java 8中&#xff0c;某些类在Javadoc中有一个小注释&#xff0c;说明它们是基于值的类 。 其中包括简短说明的链接&#xff0c;以及有关不使用它们的限制。 这很容易被忽略&#xff0c;如果这样做&#xff0c;则可能会在将来的Java版本中以微妙的方式破坏代码。 为了避免这种…

REST API的演变

每个开发人员都以某种方式接触到API 。 要么为一家大公司集成一个主要系统&#xff0c;或者使用最新的图形库生成一些精美的图表&#xff0c;要么直接与他喜欢的编程语言进行交互。 事实是&#xff0c;API无处不在&#xff01; 它们实际上代表了当今Internet的基本构建块&#…

Oracle MAF中的LOV

我们都喜欢最强大的ADF功能值列表之一。 使用它们&#xff0c;我们可以在ADF应用程序中声明性地轻松构建非常复杂的功能。 一件好事是&#xff0c;我们在Oracle MAF中也有类似的方法。 在ADF BC中&#xff0c;我们在业务服务级别&#xff08;基本上在实体或VO级别&#xff09;定…

怎么移动矩形选框工具选中的东西_ps矩形选框工具怎么用,你值得一看的技巧...

PS是一款非常好用的图片制作软件&#xff0c;我们可以使用矩形选框工具&#xff0c;选择自己需要的区域进行操作&#xff0c;下面小编就教大家ps矩形选框工具怎么用&#xff0c;希望可以帮助到大家。操作方法01首先我们打开PS进入到主界面&#xff0c;如图所示。02之后我们需要…

stream 过滤俩个字段_Java8 Stream:2万字20个实例,玩转集合的筛选、归约、分组、聚合...

点波关注不迷路&#xff0c;一键三连好运连连&#xff01;先贴上几个案例&#xff0c;水平高超的同学可以挑战一下&#xff1a;从员工集合中筛选出salary大于8000的员工&#xff0c;并放置到新的集合里。统计员工的最高薪资、平均薪资、薪资之和。将员工按薪资从高到低排序&…