我想知道如果文件名没有后缀,如何知道文件类型。
例如,一个名为的文件myfile
一开始可以是二进制或文本,系统如何知道该文件是二进制还是文本?
答案1
这file
实用程序通过 3 种方式确定文件类型:
首先是文件系统测试:在这些测试中之一统计数据对文件调用系列系统调用。这会返回不同的UNIX 文件类型:常规文件、目录、链接、字符设备、块设备、命名管道或套接字。据此进行魔法测试。
这魔法测试有点复杂。文件类型是通过称为模式的数据库来猜测的魔法文件。某些文件类型可以通过读取文件中特定位置的位或数字(例如二进制文件)来确定。魔法文件包含“神奇的数字”来测试文件是否包含它们以及应该打印哪些文本信息。那些“神奇的数字" 可以是 1-4Byte 值、字符串、日期甚至正则表达式。通过进一步测试,可以找到其他信息。如果是可执行文件,则附加信息将是它是否是动态链接或不,剥离的或不或架构。有时必须通过多次测试才能真正识别文件类型。但无论如何,进行多少次测试并不重要,它总是一个好的结果猜测。
以下是一些常见文件类型的文件中的前 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 操作系统15
(\025
) 是 IBM 的 AIX
现在语言测试开始。如果它看起来是一个文本文件,则会在该文件中搜索特定字符串以找出它包含哪种语言(C、Perl、Bash)。一些脚本语言也可以通过哈希邦( #!/bin/interpreter
) 在脚本的第一行。
如果没有任何内容适用于该文件,则无法确定文件类型,file
仅打印“数据”。
所以,你看,不需要后缀。如果设置错误,后缀无论如何都会造成混乱。
答案2
很多时候,它并不关心。您只需将它传递给程序,它要么解释它,要么不解释它。在文本编辑器中打开 .jpg 可能没有用,但您可以这样做。扩展名与文件名的其余部分一样,是为了人类的组织方便。
还可以构建可以多种方式有效解释的文件。因为ZIP文件格式开始有一个标题在文件末尾,您可以在前面添加其他内容,它仍然会作为 ZIP 文件加载。这通常用于制作自解压 zip 文件。
答案3
该信息通常可以在文件的标头中找到。该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
答案4
该file
命令通过检查(部分)文件并做出合格的猜测来应用一些启发式方法。除此之外,在一些特殊情况下可以获得额外的信息;例如#!
文本文件开头的 、BoM(字节顺序标记)或可执行文件格式的特定标头字节。#!
系统使用可执行文件中的 和 二进制标记来区分它们。