我想知道如果文件名没有后缀的情况下如何知道文件类型。
例如,一个名为的文件myfile
可以以二进制或文本开头,系统如何知道该文件是二进制还是文本?
我想知道如果文件名没有后缀的情况下如何知道文件类型。
例如,一个名为的文件myfile
可以以二进制或文本开头,系统如何知道该文件是二进制还是文本?
Answers:
该file
实用程序通过3种方式确定文件类型:
首先是文件系统测试:在这些测试中,将对文件调用stat系列系统调用之一。这将返回不同的unix文件类型:常规文件,目录,链接,字符设备,块设备,命名管道或套接字。以此进行魔术测试。
在魔术的测试是一个有点复杂。文件类型可以通过称为魔术文件的模式数据库来猜测。某些文件类型可以通过读取文件中特定位置的位或数字来确定(例如,二进制文件)。魔术文件包含“ 魔术数字 ”,以测试文件是否包含魔术数字以及应打印哪些文本信息。那些“ 魔术数字 ”可以是1-4个字节的值,字符串,日期甚至是正则表达式。通过进一步测试,可以找到其他信息。对于可执行文件,附加信息将是是否已动态链接,是否已剥离是不是还是架构。有时,必须通过多个测试才能真正识别文件类型。但是无论如何,执行多少测试都没有关系,这总是一个很好的猜测。
以下是一些常见文件类型的文件中的前8个字节,它们可以帮助我们了解这些魔术数字的外观:
Hexadecimal ASCII
PNG 89 50 4E 47|0D 0A 1A 0A ‰PNG|....
JPG FF D8 FF E1|1D 16 45 78 ÿØÿá|..Ex
JPG FF D8 FF E0|00 10 4A 46 ÿØÿà|..JF
ZIP 50 4B 03 04|0A 00 00 00 PK..|....
PDF 25 50 44 46|2D 31 2E 35 %PDF|-1.5
如果在魔术测试中找不到文件类型,则该文件似乎是文本文件,并在file
寻找内容的编码。编码的区别在于构成每个集合中可打印文本的字节的不同范围和顺序。
还会根据其十六进制值调查换行符:
0A
(\n
)对Un * x / Linux / BSD / OSX终止文件进行分类0D 0A
(\r\n
)是来自Microsoft操作系统的文件0D
(\r
)在版本9之前为Mac OS15
(\025
)将是IBM的AIX现在开始语言测试。如果它似乎是一个文本文件,则在文件中搜索特定的字符串以找出其包含的语言(C,Perl,Bash)。某些脚本语言也可以通过脚本第一行中的hashbang(#!/bin/interpreter
)进行标识。
如果文件没有任何内容,则无法确定文件类型,file
仅显示“数据”。
因此,您将看到不需要后缀。如果设置错误,后缀还是会造成混淆。
file(1)
执行的操作类似,但是实现方式非常不同。
通常,它不在乎。您只需将其传递给程序,它要么解释它,要么不解释。在文本编辑器中打开.jpg可能没有用,但不会阻止您这样做。扩展名与文件名的其余部分一样,是为了方便组织使用。
也可以构造可以多种方式有效解释的文件。因为ZIP文件格式开头是文件末尾的标头,所以您可以将其他内容放在前面,它仍将作为ZIP文件加载。这通常用于制作自解压的zip文件。
该信息通常在文件的标题中找到。该file
命令将分析目标并告诉您有关文件的信息。很多信息通常来自文件头,通常是文件头几个字节的乘积(请参见下文)。系统使用标头确定如何处理文件。 #!/bin/bash
文件开头的内容告诉系统使用bash shell解释以下脚本。ELF
告诉系统这是一个ELF可执行文件。
[~] root@www # file /bin/ls
/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
[~] root@www # file /etc/passwd
/etc/passwd: ASCII text
文件头示例:
[root@server4 ~]# xxd old_sm_logo.png | head -5
0000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR
0000010: 0000 0134 0000 006f 0806 0000 0062 bf3c ...4...o.....b.<
[root@server4 ~]# xxd /bin/ls | head -5
0000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............
0000010: 0200 3e00 0100 0000 a024 4000 0000 0000 ..>......$@.....
[root@server4 proj]# xxd resizer.sh | head -5
0000000: 2321 2f62 696e 2f62 6173 680a 5b20 2d7a #!/bin/bash.[ -z
0000010: 2022 2431 2220 5d20 2626 2065 6368 6f20 "$1" ] && echo
file
命令尝试从文件内容中猜测文件可能打算如何使用。这不是万无一失的。
file
。实际上,它确实对文件进行了分析。但是,大多数文件类型由各种标题标识。 0000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............
是ELF可执行文件的头(/ bin / ls的前几个字节)。同样#!/bin/bash
,在ASCII文件的顶部,会将其标识为Shell脚本。另一个示例:(0000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR
系统不知道文件是二进制文件还是文本文件。在所有(AFAIK)Unix类型的操作系统中,fopen(path, "rb")
与fopen(path "r")
- 完全相同- b
无效。之所以被接受,是因为标准C需要可移植到其他确实做到这一点的OS。