判断文本为文件文本还是二进制文本(C语言实现)

本文介绍了如何使用C语言判断文件是文本还是二进制,主要探讨了Linux下的file命令和magic文件规则,由于libmagic库的通用性限制,提出了根据文件头和后缀进行判断的思路,并给出了C语言代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先明确需求:用C语言实现判断文件是文本文件还是二进制文件,或者其他压缩格式文件。

文件的类型

Linux系统下,万物皆文件。
为了将所有的东西都能当成文件来管理,Linux系统将文件分成了七种类型,分别如下:

在这里插入图片描述
上表中第三、第四列是Linux下使用stat函数判断文件类型提供的一些宏定义。如判断一个文件是否属于普通文件,可以使用下面的代码:

stat(pathname, &sb);
if ((sb.st_mode & S_IFMT) == S_IFREG) {
   
   /* Handle regular file */
}

或者直接使用:

stat(pathname, &sb);
if (S_ISREG(sb.st_mode)) {
   
    /* Handle regular file */
}

但是我们的需求是判断文件是否属于文本文件还是二进制文件。而这两种都属于S_IFREG普通文件,因此无法使用上面的方法进行判断。

万能的file命令

file命令是Linux下用来检测文件类型的一个内置的命令。
大概原理就是读取一个文件的前面1024个字节,然后根据magic(/etc/magic 或者 /usr/share/misc/magic) 里对应的规则分析出文件头,并打印到屏幕上。
使用也很简单,直接file后面跟上文件名即可:

[root@ck08 ~]# file anaconda-ks.cfg
anaconda-ks.cfg: ASCII text
[root@ck08 ~]# file tls.pcap
tls.pcap: tcpdump capture file (little-endian) - version 2.4 (Ethernet, capture length 262144)
[root@ck08 ~]# file zlib-1.2.11.tar.gz
zlib-1.2.11.tar.gz: gzip compressed data, was "zlib-1.2.11.tar", from Unix, last modified: Mon Jan 16 01:36:58 2017, max compression
[root@ck08 ~]# file /usr/bin/grep
/usr/bin/grep: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=bb5d89868c5a04ae48f76250559cb01fae1cd762, stripped

从上面的示例中,可以看出file命令很强大,几乎可以识别出文件的详细类型,甚至是编码,压缩格式,大小端等具体的信息。
因此,这个命名是符合我们的需求的。
但是,我们需要的是C语言实现,因此,不得不研究magic的文件头规则。

magic文件规则

文件中的每行都指定了一个规则测试去检验文件类型,这个规则由4个域指定。分别为offset、type、test、message。

offset

指定由文件起始的第几个byte开始检验。
type

要进行检验的数据类型,即由offset那个byte开始的那个数据类型是什么。具体有哪些数据类型,可以参考magic(5)。常用的数据类型有

byte:一个byte的值
short:两个byte的值
long:四个byte的值
string:字符串
test

检验值。用于检验offset下的type是否是这个test值。使用C语言的数值或字符表示形式。
message

用于显示检验结果的信息显示。
如果type为数值类型,那么其后面可添加&value,表示先与后面的test值进行’与’操作,再进行比较。如果type为字符串类型,则其后可跟/[Bbc]*,/b表示忽略空格,/c表示忽略字母大小写。
如果test的值为数值类型,可以数值前添加=,<,>,&,^,~,分别表示相等、小于、大于、与操作、异或操作、取反操作。
如果test的值为字符串类型,可以在其前添加=、<、>。
例如,ELF文件的magic表示为:

# ELF
#0string        ELF        ELF
 0    string        \177ELF        ELF
>4    byte        1        32-bit
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值