最近项目有个判断文件类型的需求,经过调研发现目前判断文件类型的方式主要有两种:一是打开文件,匹配文件内容(当然通过文件后缀判断也可以,但是不准确。)。二是使用libmagic库进行判断,linux操作系统中file命令就是使用了libmagic库。这里我介绍使用libmagic静态库的方式。
libmagic静态库链接到项目中进行文件类型判断。使用静态库适合打包成可执行程序在不同的机器上执行,但是同时需要将magic.mgc文件一起打包,缺少该文件则无法判断文件类型。
首先下载libmagic静态库,下载地址(https://anaconda.org/bioconda/libmagic/files)
然后引用头文件magic.h并且链接静态库libmagic.a到工程中,同时还需要将/share/misc/magic.mgc文件拷贝到项目配置文件中。
最后编写代码如下
#include "magic.h" #include#include bool isELFFilePath(magic_t handle_, std::string path) { if (handle_ == NULL) { return false; } auto type = magic_file(handle_, path.c_str()); if (type == NULL) { return false; } std::string file_type = type; if (file_type.find("ELF") != std::string::npos)//判断文件是否为ELF文件 { return true; } return false; } magic_t initFileHandle() { std::string magic_path = "/usr/local/magic.mgc";//数据库文件路径 auto handle_ = magic_open(MAGIC_NONE | MAGIC_COMPRESS); if (handle_ == NULL) { printf("magic_open handle failed!"); return NULL; } if (magic_load(handle_, magic_path.c_str()) != 0) { magic_close(handle_); return NULL; } return handle_; } int main() { auto handle_ = initFileHandle(); if (handle_ == NULL) { return -1; } std::string file = "/home/test.jpg"; if (isELFFilePath(handle_, file)) { printf("file:%s is ELF file!", file.c_str()); } else { printf("file:{} is not ELF file!", file.c_str()); } }
需要注意的是数据库文件路径如果填写NULL,默认路径为/usr/share/misc/magic.mgc
编译时候发现出现报错:
经查阅得知是没有指定链接参数-lz(/usr/lib/libz.so,/usr/lib/libz.a ),链接命令加上-lz问题解决。
执行结果如下:
通过命令查看/home/test.jpg文件如下:
可以证实这个代码判断正确,事实上这确实是一个执行程序重命名后的文件。同时也反应通过后缀名的方式判断文件类型存在不准确性。



