在《文件类型识别的实现思路》讲文件识别实现方案的文章中,我们提到可以使用libmagic库,今天我们就来具体讲一下libmagic的API使用方法:

1、获取libmagic库

这里有两种方法,一种是直接从https://anaconda.org/bioconda/libmagic/files这个网站下载libmagic的库。

一种是从github上下载file命令的源码:https://github.com/file/file,然后按照文档进行源码编译,操作步骤如下:

1)下载源码,这里指定5.25版本:

git clone https://github.com/file/filegit checkout FILE5_25cd file

2)源码编译:

autoreconf -f -imake distclean./configure --disable-silent-rules --enable-staticmake -j4

2、libmagic库的说明

使用libmagic,需要头文件magic.h,静态库libmagic.a或者动态库libmagic.so,以及文件类型识别数据库magic.mgc。

我们以下载的libmagic-5.25开发库为例,magic.h在include目录下,libmagic的库在lib目录下,magic.mgc文件在share/misc目录下。

3、libmagic的使用

下面我们以一个简单的例子说明,如何使用libmagic进行文件类型识别,以下是我写的简单的测试源码file_test.c:

#include "magic.h"#include #include int main(int argc ,char *argv[]){ char *mgc_file="share/misc/magic.mgc"; magic_t ctx = magic_open(0); if (ctx == NULL) {printf("magic open failed\n");goto error; } if (magic_load(ctx, mgc_file) != 0) {printf("magic file load failed\n");goto error; } if(argc > 1) {const char *file_desc = magic_file(ctx, argv[1]);if(file_desc){printf("file-type: %s\n", file_desc);} }magic_close(ctx); return 0;error: if (ctx != NULL) {magic_close(ctx);ctx = NULL; }return 1;}

编译file_test.c:

gcc -g file_test.c -o file_test -I include/ -L lib/ -static -lmagic -lz 

找一个png文件测试一下:./file_test /tmp/1.png,可以看到程序打印出了png文件的描述信息

上面的file_test.c主要用到了libmagic的四个API:

  • magic_open:打开magic库,其实就是内部的初始,然后获得magic_t句柄
  • magic_load:根据指定的magic.mgc文件,加载该文件
  • magic_file: 文件类型识别,传入magic_t句柄和要识别的文件名称
  • magic_close: 使用完成后,关闭magic库
    除了使用magic_file传入文件名进行文件类型识别外,libmagic还提供了magic_buffer这个函数进行文件类型识别:
public const char *magic_buffer(struct magic_set *ms, const void *buf, size_t nb)

magic_buffer传入的是magic_t句柄,要识别的一段缓冲区的起始地址以及缓冲区的长度,其实就可以理解为我们把magic_file中的文件内容读到了一段内存中,然后进行识别的,差别不大。

好了,libmagic库的使用就讲到这里了,是不是比较简单呢” />https://anaconda.org/bioconda/libmagic/files下载使用,如果想研究源码,就从github上下载file命令的源码进行研究。