什么是MIME Type
- MIME Type是用于描述文件的類型的一種表述方法,其將文件劃分為多種類型,方便對其進行統一的管理。
- MIME Type指定了文件的類型名稱、描述、圖標信息,同時通過與.desktop應用程序描述文件整合,指定了文件的打開方式。
- MIME type是被file manager使用,而不是Gnome或者Ubuntu系統本身。
以GIMP的.desktop為例說明:
[Desktop Entry]
Version=1.0
Type=Application
Name=GNU Image Manipulation Program
GenericName=Image Editor
Comment=Create images and edit photographs
Exec=gimp-2.7 %U
TryExec=gimp-2.7
Icon=gimp
Terminal=false
Categories=Graphics;2DGraphics;RasterGraphics;GTK;
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=GIMP
X-GNOME-Bugzilla-Component=General
X-GNOME-Bugzilla-Version=2.7.2
X-GNOME-Bugzilla-OtherBinaries=gimp-2.7
StartupNotify=true
MimeType=application/postscript;application/pdf;image/bmp;image/g3fax;image/gif;image/x-fits;image/pcx;image/x-portable-anymap;image/x-portable-bitmap;image/x-portable-graymap;image/x-portable-pixmap;image/x-psd;image/x-sgi;image/x-tga;image/x-xbitmap;image/x-xwindowdump;image/x-xcf;image/x-compressed-xcf;image/tiff;image/jpeg;image/x-psp;image/png;image/x-icon;image/x-xpixmap;image/svg+xml;application/pdf;image/x-wmf;image/jp2;image/jpeg2000;image/jpx;image/x-xcursor;
MimeType字段說明了這個程序支持的MIME types
Exec字段說明了程序的打開方式,Exec字段最后的%U或%f很重要,其決定了這個程序時候能顯示在文件管理器的open with清單中。
參考URL:
http://askubuntu.com/questions/16580/where-are-file-associations-stored
https://specifications.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html#idm140625828640704
https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
https://specifications.freedesktop.org/desktop-entry-spec/0.9.5/ar01s07.html
誰來決定MIME type的默認程序
- mime文件類型描述文件,定義了每個MIME type的特征參數,以及每個何種類型的文件歸屬到這個MIME下
- .desktop應用程序描述文件,說明了程序的打開方式,也指定了其支持的MIME type
- mimeinfo.cache 通過抓取.desktop文件的MIME字段信息,將上述兩種描述文件合二為一,形成一個查詢數據庫,每個MIME type文件打開時,將通過這個文件尋找打開程序。
- 如果一個MIME type對應到多個.desktop應用程序描述文件,通過抓取而來的mimeinfo.cache并不能決定誰更優先,因為多個.desktop文件之間并沒有優先級定義。面對這個場景,最終的默認程序是由mimeapps.list文件定奪的,其由用戶人工配置,決定同一個MIME type對應多個.desktop程序時,哪個程序優先級更高,更高優先級的程序即是族中的默認程序。
mimeapps.list在系統中有多個路徑存在,每個路徑的優先級是不同的,修改時需要注意。
Freedesktop標準化
參考URL:
https://specifications.freedesktop.org/mime-apps-spec/mime-apps-spec-latest.html 重要
https://wiki.archlinux.org/index.php/Default_applications 次要
在舊時代,KDE和GNOME各自為政,為了在不同的Desktop Manager上統一應用程序打開方法,Freedesktop.org組織定義了多個標準規范,以實現應用的統一管理:
-
Shared MIME database文件類型描述數據庫,這個數據庫描述了每一個文件類型(MIME type)的參數特征(名稱、、別名、描述、圖標),以及滿足何種條件才能將其劃分到對應的MIME類別。
- MIME type描述文件,位于/usr/share/mime/packages/(.xml),其每一個文件類型(MIME type)的參數特征(名稱、、別名、描述、圖標),以及滿足何種條件才能將其劃分到對應的MIME類別。
- 單獨索引每個MIME type描述文件是非常不高效的,所以Freedesktop引入了Shared MIME database,其是一個靜態數據庫(文本文件/usr/share/mime/mime.cache
此cache文件不建議用戶修改,可以通過修改上述靜態數據庫,并通過update-mime-database /usr/share/mime/命令更新cache文件
),描述了每個MIME type的特征。初期的數據整合了早期KDE和GNOME的文件類型描述信息,并逐步更新。 - 用戶可以自定義自己描述的MIME type描述文件到/usr/share/mime/packages/(.xml),并通過update-mime-database /usr/share/mime/ 命令更新到數據庫文件中。
Desktop Entry specification應用程序描述文件(.desktop),這個文件描述了系統上安裝的應用程序的參數特征(名稱、啟動方法、圖標、支持的MIME type)。這個描述文件除了用于打開程序外本身、打開MIME type文件的關聯程序,還負責提供給Desktop Manager構建應用程序Menu和索引)
-
mime-apps-spec-1.0關聯MIME type和application,標準規定了一個文件可以默認被哪個應用程序(上述Desktop Entry specification定義)打開、如何修改默認打開程序、如何增加刪除MIME type與application的關聯。
- 每個應用程序描述文件雖然已經指定了各自支持的MIME type,但是如果每次文件打開前都去遍歷一邊所有的描述文件,執行效率將會非常低下。所以就需要一個關聯數據庫,負責將application(應用程序描述文件)與MIME type(Shared MIME Database)對應起來。這個數據庫是一個文本文件靜態數據庫(/usr/share/applications/mimeinfo.cache
此cache文件不建議用戶修改,可以通過修改每個單獨的.desktop文件,并通過update-desktop-database /usr/share/mime/命令更新數據庫
)。 - 用戶可以自定義應用程序的打開方式到/usr/share/appliacaions(.desktop),并通過update-desktop-database /usr/share/applications/命令更新到數據庫中。
- 每個應用程序描述文件雖然已經指定了各自支持的MIME type,但是如果每次文件打開前都去遍歷一邊所有的描述文件,執行效率將會非常低下。所以就需要一個關聯數據庫,負責將application(應用程序描述文件)與MIME type(Shared MIME Database)對應起來。這個數據庫是一個文本文件靜態數據庫(/usr/share/applications/mimeinfo.cache
文件默認打開程序優先級
參考URL:https://wiki.debian.org/MIME (最終改變了作者對mimeapps.list和mimeinfo.cache的關系的認識,以及整個MIME體系的認識)
update-desktop-database程序通過從每個.desktop文件中抓取其關聯的MIME type,并形成mime type與application關聯數據庫,但是因為是抓取的方式獲得的關聯關系,如果一個mime type對應有多個application(.desktop),則mimeinfo.cache數據庫是不能分辨出優先級的。
這時就需要另一個與mimeinfo.cache數據庫格式相似的文件mimeapps.list,其負責指定每個mime type在發生多程序關聯時,哪個程序優先級高,mimeapps.list在系統中有多個路徑存在,見下表(文件優先級自高到底):
Path | Usage |
---|---|
$XDG_CONFIG_HOME/$desktop-mimeapps.list | user overrides, desktop-specific (for advanced users) |
$XDG_CONFIG_HOME/mimeapps.list | user overrides (recommended location for user configuration GUIs) |
$XDG_CONFIG_DIRS/$desktop-mimeapps.list | sysadmin and ISV overrides, desktop-specific |
$XDG_CONFIG_DIRS/mimeapps.list | sysadmin and ISV overrides |
$XDG_DATA_HOME/applications/$desktop-mimeapps.list | for completeness, deprecated, desktop-specific |
$XDG_DATA_HOME/applications/mimeapps.list | for compatibility, deprecated |
$XDG_DATA_DIRS/applications/$desktop-mimeapps.list | distribution-provided defaults, desktop-specific |
$XDG_DATA_DIRS/applications/mimeapps.list | distribution-provided defaults |
注意1:mimeapps.list的前身是defaults.list,但是已經被廢棄不用了。參考URL:https://wiki.archlinux.org/index.php/Default_applications
注意2:如果修改了mimeapps.list文件,且更新了數據庫緩存,但是依舊不生效,就需要看一下修改的文件的優先級,有沒有更高級別的文件覆蓋了你的操作。
作者一開始沒有搞清楚整個工作模式時,是使用strace跟蹤nautilus才發現的這個問題。
查看文件的MIME type及其該MIME關聯的application打開方式:
ray@ray-ThinkPad-X250:~/Desktop$ mimetype topo-WLAN.graphml
topo-WLAN.graphml: application/yed
ray@ray-ThinkPad-X250:~/Desktop$ gvfs-mime --query application/yed
Default application for 'application/yed': yEd.desktop
Registered applications:
yEd.desktop
Recommended applications:
yEd.desktop
ray@ray-ThinkPad-X250:~/Desktop$
不建議使用xdg-mime query filetype命令查看MIME打開方式,其通過/usr/share/mime/目錄下的文件決定輸出內容,如果mime-type是通過alias定義的,沒有實際的文件,則查找失敗。
gvfs-mime雖然也是讀取/usr/share/mime目錄下的文件,但是它可以識別出alias,雖然有時候也是不準確!!!
自定義MIME TYPE,并指定打開程序
參考URL:
https://wiki.archlinux.org/index.php/Default_applications
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Desktop_Migration_and_Administration_Guide/File_Formats.html
- 自定義MIME TYPE
icon 自定義:
http://techmonks.net/how-to-add-a-custom-filetype-to-linux/
https://help.ubuntu.com/community/AddingMimeTypes
https://wiki.archlinux.org/index.php/Icons
Linux 的icons也分為很多種類,專門的icon theme都會分類到指定的icon類別(不同的目錄),mimetypes也是專門的目錄。
用戶自己創建的mimetypes icons存放在~/.local/share/icons
目錄的子目錄mimetypes下:
ray@ray-ThinkPad-X250:~/.local/share/icons$ ls -al ~/.local/share/icons/hicolor/32x32/mimetypes/
total 12
drwx------ 2 ray ray 4096 Feb 28 12:32 .
drwx------ 4 ray ray 4096 Feb 28 12:32 ..
lrwxrwxrwx 1 ray ray 7 Feb 28 12:32 gnome-mime-yEd.png -> yEd.png
-rw------- 1 ray ray 1922 Feb 28 12:32 yEd.png
ray@ray-ThinkPad-X250:~/.local/share/icons$ ls -al ~/.local/share/icons/hicolor/32x32/apps
total 12
drwx------ 2 ray ray 4096 Feb 26 16:30 .
drwx------ 4 ray ray 4096 Feb 28 12:32 ..
-rw------- 1 ray ray 1350 Feb 26 16:30 chrome-coobgpohoikkiipiblmjeljniedjpjpf-Default.png
ray@ray-ThinkPad-X250:~/.local/share/icons$
配置自定義mime icon步驟如下:
- 尋找一個png文件,并確定其尺寸大小。(文件屬性可以看到)
- 不用復制文件到上述mimetypes icon目錄,使用如下命令實現:
xdg-icon-resource install --size 32 --context mimetypes yEd.png
- 更新MIME數據庫
sudo update-mime-database /usr/share/mime
- 配置.desktop文件關聯MIME TYPE
ray@ray-ThinkPad-X250:~/.local/share/applications$ sudo vim ~/.local/share/applications/yED.desktop
#!/usr/bin/env xdg-open
[Desktop Entry]
Type=Application
Name=yEd Graph Editor
Exec=/bin/sh "/home/ray/Applications/yEd/yEd" %f
Icon=/home/ray/Applications/yEd/.install4j/yEd.png
Categories=Player;
MimeType=application/yed;
- 更新.desktop文件與MIME TYPE關聯數據庫
$ update-desktop-database ~/.local/share/applications
thunderbird下的MIME
參考URL:http://kb.mozillazine.org/Actions_for_attachment_file_types
通過strace可以發現Thunderbird調用了/etc/mailcap和/etc/mime.types文件(有限調用用戶目錄下的~/.mimetypes文件)決定文件的打開方式,這兩個文件是通過update-mime命令更新維護的,區別與前邊的update-mime-database。
正常情況下thunderbird與系統文件系統的標準MIME配置是一樣的,可以正確的識別文件的MIME類型并對應打開程序。
但是thunderbird的MIME類型判斷不完全是通過擴展名來檢測的,thunderbird使用郵件系統的正文(源代碼)指定的MIME類型和附件的擴展名聯合來尋找關聯的application,正常情況下也是沒有問題的,但是。。。。。。總有一些不守規矩的郵件內容(尤其是一些垃圾第三方郵件客戶端),會指定錯誤的MIME類型,比如將xls和xlsx混淆關聯,所以將會導致thunderbird判斷不出文件的MIME類型,進而無法提供默認的application,所以會經常看到默認的gedit程序總是被“寵幸”作為last backup。
目前還沒有找到好的辦法解決這個問題,隨后再研究吧。
2016.08.03 找到兩個之前版本靠譜的Thunderbird Add-on:
OPENATTACHMENTBYEXTENSION
根據文件擴展名來選擇打開的程序,可以解決Thunderbird下的問題,但是最新版本測試結果是中文文件打開還是有問題,charset設備為gb2312也是不可以的。
Gnome Open或OpenX
要求DM必須是GNOME,通過調用gnome-open程序讓Nautilus來判斷文件類型,并選擇合適的打開方式。它會生成一個新的MIME分類到thunderbird,名字是"application/gnomeopen",強制指定通過/usr/bin/gnome-open程序打開。再通過插件Overlay的方式替換掉thunderbird處理附件的JS腳本,修改腳本打開附件的方法固定使用"applicaiton/gnomeopen"這個MIME。測試結果是已經失效,應該是JS腳本因為版本升級發生了變化,自己嘗試修改也未果。
最終的可用的方法是,通過Gnome Open插件帶來的靈感,在unknow文件打開時,選擇打開方式為/usr/bin/gnome-open,簡化操作。