在C语言中检测文件MIME类型出错,magic与GIO库结果异常求解
问题排查与修复方案
magic库识别失效的原因及解决
你遇到的magic库返回application/octet-stream,大概率是初始化时没加载完整的系统魔法规则文件。默认调用magic_open(MAGIC_MIME_TYPE)可能只启用了基础检测逻辑,而file命令用的是系统完整的魔法规则集(通常路径是/usr/share/file/magic或/usr/share/misc/magic,不同发行版略有差异)。
修复代码示例:
#include <magic.h> #include <stdio.h> int main() { magic_t magic = magic_open(MAGIC_MIME_TYPE); if (!magic) { fprintf(stderr, "magic_open failed\n"); return 1; } // 加载系统完整魔法文件,路径根据你的发行版调整 if (magic_load(magic, "/usr/share/file/magic") != 0) { fprintf(stderr, "magic_load failed: %s\n", magic_error(magic)); magic_close(magic); return 1; } const char *mime = magic_file(magic, "fake-pdf.txt"); printf("MIME type: %s\n", mime); magic_close(magic); return 0; }
如果需要更接近file命令的输出(带描述),可以把MAGIC_MIME_TYPE换成MAGIC_MIME。
GIO库识别错误的原因及解决
GIO的g_content_type_guess默认会优先参考文件扩展名,而且如果不传入文件内容字节,它可能只做简单检测。要强制基于文件内容识别,需要读取文件头部的特征字节传给函数,同时确保系统的shared-mime-info数据库是最新的。
修复代码示例:
#include <gio/gio.h> #include <stdio.h> int main() { const char *file_path = "fake-pdf.txt"; GError *error = NULL; GFile *file = g_file_new_for_path(file_path); GFileInputStream *stream = g_file_read(file, NULL, &error); if (!stream) { fprintf(stderr, "Failed to read file: %s\n", error->message); g_error_free(error); g_object_unref(file); return 1; } guint8 buffer[1024]; gsize bytes_read = g_input_stream_read(G_INPUT_STREAM(stream), buffer, sizeof(buffer), NULL, &error); if (error) { fprintf(stderr, "Failed to read stream: %s\n", error->message); g_error_free(error); g_object_unref(stream); g_object_unref(file); return 1; } gboolean is_certain; gchar *content_type = g_content_type_guess(file_path, buffer, bytes_read, &is_certain); printf("Content type: %s, Certain: %d\n", content_type, is_certain); // 可以进一步转成MIME类型 const char *mime_type = g_content_type_get_mime_type(content_type); printf("MIME type: %s\n", mime_type); g_free(content_type); g_object_unref(stream); g_object_unref(file); return 0; }
另外,运行sudo update-mime-database /usr/share/mime更新MIME数据库,确保GIO能获取到最新的文件特征规则。
为什么file命令能正确识别
file命令本身就是基于magic库实现的,但它启动时会自动加载系统完整的魔法规则文件,并且默认启用了更全面的检测逻辑(比如深入分析文件头部多字节特征),所以能正确识别扩展名错误的文件。
内容的提问来源于stack exchange,提问作者Googlebot
相关产品推荐
相关产品推荐

