确定文件的MIME类型

3

我该如何确定文件的mime类型(在OCaml中)?

我正在尝试设置GtkSourceView控件的语言,但要做到这一点,我需要先确定语言。我唯一能想到的方法是使用mime类型 - 有一个函数将返回正确的语言,如下所示:

GSourceView.source_languages_manager#get_language_from_mime_type : string -> source_language option

我真的不想在我的源代码中硬编码语言。如果在OCaml中无法确定MIME类型(在查阅文档后,我还没有找到方法),那么也许有其他方法可以确定源语言吗?

4个回答

4
在研究包括此功能在内的gedit源代码后,我发现了glib中的一种方法可以为我完成此操作。 这个答案 提供了g_file_info_get_content_type()方法的一个示例用法。 glib还提供了g_content_type_get_mime_type() 方法。不幸的是,目前这些函数还没有可用的封装,这意味着我可能需要自己生成封装。

3

大多数语言都缺乏这个功能,因此如果在OCaml中找到它,我会感到非常惊讶。Apache使用mime.types文件实现了这一点-您可以在那里查找提示。这是最常见的方法-一个将扩展名映射到MIME类型的巨大表格。您可以轻松地在OCaml中实现它:

let mimetype_of_extension = function
    | "txt" | "log" -> "text/plain"
    | "html" | "htm" -> "text/html"
    | "zip" | "application/zip"
...

另一种方法是查看文件内容,但这就需要您了解各种文件格式。但这并没有帮助太多,因为所有语言的源文件通常都被视为“text/plain”,它们无法通过MIME类型进行区分;因此我真的不知道您的“get_language_from_mime_type”函数是做什么的。但是,各种源文件的文件名扩展名更或多或少是标准化的,因此如果您知道扩展名,就会知道所使用的语言。获取扩展名只需从文件名中提取最后一个句点后面的内容即可。
let extension_of_filename filename =
    let pos = (String.rindex filename '.') + 1 in
    let len = String.length filename in
    let ext = String.create (len - pos) in
    String.blit filename pos ext 0 (len - pos);
    ext;;

嗯,好的,简单的编程语言都很容易理解,但 Brainfuck 和 OCaml 就不一样了。之后就容易了 - “c” 是 C 语言程序,“h” 也是;“ml” 则表示 OCaml 程序等等。


2
OP已经依赖于GtkSourceView,因此他可能想要一个返回位于.../share/mime/types中列出的类型的函数,该文件由GtkSourceView或其依赖项之一安装。该文件列出了"text/x-erlang"、"text/x-eiffel"等(只是浏览一下"e" :))。但是,在此文件中未列出这些类型的规范扩展名。 - Pascal Cuoq
1
我认为 get_language_from_mime_type 最终是从 eiffel.lang、erlang.lang 等配置文件中获取语法描述(高亮显示等),这些文件位于 .../share/gtksourceview-2.0/language-specs/。 - Pascal Cuoq
@PascalCuoq - 没错,那些是我想要查找的 MIME 类型 - 这是否意味着我必须自己创建一个大的查找表,并根据文件扩展名返回 MIME 类型? - a_m0d
抱歉,我不熟悉GtkSourceView。如果您已经有像@Pascal描述的文件,您可以编写一个解析器函数来解析它,而无需自己创建查找表。 - Amadan

2
在GTK中,你可以封装已经找到的函数。
解析/etc/mime.types也不难 - 它是一个简单的以空格分隔的文件。我相信Ocsigen和Ocamlnet都包含了这样做的代码,但我不知道它们是否很容易访问(例如,Ocamlnet netstring库公开的一个函数)。

1

这可能不是确定源代码类型的最佳方法(在我看来,使用/etc/mime.types最好),但也有libmagic的OCaml绑定可供使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接