这里写目录标题
如何判断任意文件类型
1问题
从客户那里拿来的数据文件要入库,不知道是哪种数据库类型,也不知道是哪种备份方式。
进一步没有后缀的文件,如何判断文件类型并使用相对应的工具并解析之?
2可用的方案
不能简单的通过后缀名来判断文件的类型
一方面文件后缀名可以随意修改或者删除。
另一方面在Linux上一切对象皆文件,完全不需要后缀名。
https://www.zhihu.com/question/422144033
很多文件在文件头都会标识这种文件的类型,这几个字节也被称为"魔数"。
“魔数"是一个数字,通常使用十六进制表示。
你可以通过如下命令查看指定文件的"魔数”。
hexdump -C 文件路径 | less
2.1 使用HEX编辑工具
EmEditor
https://zh-cn.emeditor.com/text-editor-features/more-features/binary-editing/
Ultraedit
https://www.ultraedit.com/language/hex-editor.html
WinHex
https://www.x-ways.net/winhex/
DiskGenius
https://www.diskgenius.cn
010Editor
http://www.sweetscape.com/010editor/
notepad++
https://notepad-plus-plus.org/downloads/
需要安装插件HEX-Editor
Visual Studio Code
https://code.visualstudio.com/
安装Hexdump
Atom
https://atom.io/
https://atom.io/packages/hex-view
Sublime Text
https://www.sublimetext.com/
安装HexViewer
超大文件可以只读取前1024字节内容来查看。
https://bbs.csdn.net/topics/350091771
printf "\001\002\003\004" | head -c 3 | tail -c 2 | od -t x1
ping qq.com > bigFile
head -c 32 bigFile > bigFile.32
dd if=bigFile of=bigFile.1k bs=1 skip=0 count=32
2.2 使用代码读取“魔数”
python
https://github.com/h2non/filetype.py
pip install filetype
2018-02-18
https://www.cnblogs.com/zhaoyingjie/p/8452934.html25
May 2019
https://github.com/white-shiro-bai/move_file_by_type
根据文件的类型把目录和子目录中的所有文件归类。
文件类型识别依赖 mediainfo.dll 和 pymediainfo
javascript
https://gist.github.com/tom-field/ccdea3c53d4319f746d26828b2f862c7#file-js
https://codepen.io/movii/pen/oBLNoJ
java
22 Feb 2019
https://github.com/briarbear/file_type_recognition
基于Apache POI实现对常见文件(包括无后缀名)类型的识别
8 Jan 2018
https://github.com/LunziQwQ/File-Extension-Changer
智能识别文件类型并补全后缀名
15 Dec 2017
https://github.com/leleliu008/FileTypeChecker-java
根据魔数检测文件的类型,java实现
C/C++
16 Nov 2017
https://github.com/tokgolich/fmti
File format identification–文件类型识别
C#
11 Sep 2015
https://github.com/william0227/filetype
判断文件类型
2019-03-01
https://blog.csdn.net/liujia_It/article/details/88058481、
可能这个种方式有缺陷,但是应该是比较好的判断方式。
因为网上很多人说不一定取前两个字节,有的文件可能不止,至于原因我也不知道为啥。
如果有朋友知道麻烦留个言,让我学习下
2014-01-23
https://www.cnblogs.com/bubugao/p/FileStream.html
https://www.cnblogs.com/babycool/p/3531696.html
判断文件真实的类型,不是通过扩展名来判断
php
2011年12月09日
http://www.nowamagic.net/librarys/veda/detail/836
文件签名一般都在文件的头部,如果你用十六进制方式查看文件,你就可以看到文件的一些签名信息。
2015年07月10日
php获取文件类型和文件信息的方法
https://www.jb51.net/article/69262.htm
2016年10月07日
php文件类型MIME对照表(比较全)
https://www.jb51.net/article/94118.htm
2019-09-20
https://www.php.cn/php-ask-430531.html
2017-04-10
https://blog.csdn.net/qq_21386275/article/details/69987371
方法一:pathinfo
说明:但是该方法仅仅只能根据文件后缀来判断文件类型
方法二:
F
I
L
E
S
如
果
是
p
h
p
上
传
文
件
,
则
可
以
用
_FILES 如果是php上传文件,则可以用
FILES如果是php上传文件,则可以用_FILES[‘uploadfile’][‘type’]来获取,原理同上
方法三:php Fileinfo 获取文件MIME类型(finfo_open)
说明: 该方法需要php5.3.0+版本。即便是原文件被改过后缀,依然可以读到原文件类型。
方法四:读取文件头六个字节作为判断。
说明: 这个方法有缺陷,不同类型的文件,文件头4个字节可能会相同,并且部分文件类型表示文件类型的字符串,少于4个字节。可以考虑将方法三和方法四结合使用。
(对照表的英文大写要改成小写,第一个数字为0时要省略,eg:504B0304读到的是504b34)
2.3 可能的缺陷
https://github.com/dromara/hutool/issues/259
现在的判断方法是根据文件头的字节内容判断,存在很大的误差,比如docx认为是个zip文件等等,还不如直接用File的probeContentType判断准确。
疑问:
1、为什么采用现在的处理方式?
2、有没有其他更好的识别方式?
3 文件头信息
文件是操作系统中的概念。
http://blog.fpliu.com/it/data/file#checkType
每个操作系统通常都会有文件系统。
而文件系统就是用来管理文件的。
3.1最好使用开源维护中的项目
1 June 2021
GCK’S FILE SIGNATURES TABLE
https://www.garykessler.net/library/file_sigs.html
https://fileinfo.com/
https://filext.com/
https://www.file-extensions.org/
3.2其次从成熟商业软件中提取
各类文件头信息
https://www.jianshu.com/p/4af4d5fe5dbd
https://www.cnblogs.com/qfcndtt/archive/2012/05/08/2489761.html
https://blog.csdn.net/qq_42777804/article/details/98876646
一、从Ultraedit中提取出来的文件头信息,两个字符算一字节(十六进制)
二、从winhex中取出的文件头列表
3.3 具体项目指定白名单
2020-07-31
常见文件文件头
https://zhuanlan.zhihu.com/p/158980459
2019-02-18
128个常见的文件头信息对照表
http://www.manongjc.com/article/56456.html
2019-08-08
常见的文件头信息对照
https://blog.csdn.net/qq_42777804/article/details/98876646
4 文件扩展名
Windows系统文件按照不同的格式和用途分很多种类,为便于管理和识别,在对文件命名时,是以扩展名加以区分的,即文件名格式为: “主文件名.扩展名”。这样就可以根据文件的扩展名,判定文件的种类,从而知道其格式和用途。
https://support.microsoft.com/zh-cn/windows/windows-%E4%B8%AD%E7%9A%84%E5%B8%B8%E8%A7%81%E6%96%87%E4%BB%B6%E6%89%A9%E5%B1%95%E5%90%8D-da4a4430-8e76-89c5-59f7-1cdbbc75cb01
Windows 文件名包含由句点分隔的两个部分:第一部分是文件名,第二部分是定义文件类型的三字符扩展名或四字符扩展名。 例如,在“expenses.xlsx”中,文件名的第一部分是“expenses”,扩展名为“xlsx”。
4.1 查看已注册文件类型
FileTypesMan 用来查看系统中已注册文件类型的小工具。
https://www.nirsoft.net/utils/file_types_manager.html
4.2 常见文件类型及扩展名
https://www.cnblogs.com/xiaomulei/p/10108198.html
文件类型 | 扩展名及打开方式 |
---|---|
文档文件 | txt、docx、xlsx、pdf、wps、html、js、css |
压缩文件 | rar、zip、7z、tar、gz |
图形文件 | bmp、gif、jpg、png、tif、psd |
声音文件 | wav、mp3、aac、flac |
视频文件 | avi、mpeg、mov、mkv、flv、swf |
可执行文件 | exe、com、dll、so |
批处理文件 | bat、cmd、ps1、sh |
4.3 文件扩展名作用
https://zh.wikipedia.org/zh-hans/%E6%96%87%E4%BB%B6%E6%89%A9%E5%B1%95%E5%90%8D
副档名(Filename Extension,或作延伸档名、后缀名)是早期操作系统(如VMS/CP/M/DOS等)用来标志档案格式的一种机制。
文件扩展名更重要的作用是让系统决定当用户想打开这个文件的时候用哪种软件运行
这种命名法有着很大的缺陷,所以某些作业系统采用更精确的档案魔术编号(magic number)来判断档案类型。
5 魔术数字
https://zh.wikipedia.org/wiki/%E9%AD%94%E8%A1%93%E6%95%B8%E5%AD%97_(%E7%A8%8B%E5%BC%8F%E8%A8%AD%E8%A8%88)#%E5%9C%A8%E6%96%87%E4%BB%B6%E4%B8%AD
在程序设计中,魔术数字(magic number)可能指:用于识别一个文件格式或协议类型的一段常量或字符串,例如UNIX的特征签名。
魔术数字也会在文件中使用。在特定文件格式中加入固定数值和固定字符串,然后便可以通过检查文件是否包含这些数据来快速地识别文件格式。例如:GIF文件开头会包含GIF89a(47 49 46 38 39 61)或GIF87a(47 49 46 38 37 61)这两种字符串。
Hexspeak
https://zh.wikipedia.org/wiki/Hexspeak
Hexspeak(16进制魔术数字)是一种类似Leet的英文单词转写形式。
较有名的魔术数
16进制魔术数在许多处理器、操作系统和调试工具中都得到应用,且尤常作为调试量使用。
0x0000000FF1CE 是微软Office组件产品代码的最后一部分。
0x1BADB002(“I bad boot”)为多重引导(Multiboot Specification)标头。
0x8BADF00D(“ate bad food”)为iOS应用程序崩溃报告中的超时标识符。
0xCAFEBABE(“cafe babe”)在Mach-O格式文件中用于标识通用二进制目标文件,同时也在Java中用于识别Java字节码类文件。
0xCAFED00D(“Cafe Dude”)在Java中用于识别Pack200压缩格式。
0xDEADDEAD(“dead dead”)是蓝屏时显示的错误代码 。
0xDEFEC8ED(“defecated”)在OpenSolaris的核心文件中使用。
0xE011CFD0 在微软Office文件中使用,小端序下表示为D0CF11E0,也即“docfile0”。
linux
https://sites.google.com/site/polarisnotme/linux/ubuntu/mime%E7%B1%BB%E5%9E%8Bunderlinux
为了更好的判断文件类型,在 linux下同时采用两种方式:
优先采用magic方式,其次才采用文件扩展名方式。
所谓magic方式,就是根据文件内容来判断。
绝大多数文件,内部都有一些特定的标记,这些标记称为magic,比如BMP图片文件以BM两个字符开头,BM就是一个magic。
虽然即使采用了双保险机制也有误判的可能,但概率已经大大降低了。
文件类型的数据信息
在linux下,关于文件类型的信息通常放在/usr/share/mime、/usr/local/share/mime和用户目录下,所有应用程序可以共享这些信息。
Linux比windows的做法科学之处
Linux采用了双保险机制,对文件类型的判断更正确,出错的概率更小。
Linux分离文件类型判断信息和文件关联方式,这样文件类型信息可以被重用。
https://docs.huihoo.com/redhat/rhl-gsg-zh_CN-9/s1-managing-file-types.html
如果一个文件没有扩展名,或者它与它的扩展名不符时怎么办呢?
譬如,你找到了一个叫做 saturday
的文件,它没有扩展名。使用 file
命令,你就可以判定这个文件的类型:
file saturday
nm 目标文件格式分析
https://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/nm.html
nm 命令显示关于指定 File 中符号的信息,文件可以是对象文件、可执行文件或对象文件库。
如果文件没有包含符号信息,nm 命令报告该情况,但不把它解释为出错条件。
nm 命令缺省情况下报告十进制符号表示法下的数字值。