RubyにおけるMIME型判別ライブラリの比較
Rubyでファイルに対するMIME型の自動判別を行うには、次のライブラリが便利です。
これらの違いは判別方法にあります。MIME::Typesは、IANAに登録されているMIME型情報を元に、ファイルの拡張子から判別を行なうので、拡張子が付いていないものに対しては無力です。一方shared-mime-infoは、freedesktop.orgの提供するMIMEデータベースを使い、拡張子とファイル内容の両面から判別することが出来ます。よって、拡張子が付いているとは限らない環境や付いている拡張子が信用できない場合、shared-mime-infoを使うしかありません。
なお、どちらも pure ruby であり、また gem を使って簡単にインストールすることが出来ます。
gem install mime-types gem install shared-mime-info
以下に簡単に使い方をまとめておきます。
MIME::Typesライブラリ
クラスMIME::Typesのクラスメソッド type_for を使って判別を行ないますが、返り値がMIME::Typeオブジェクトのリストであることに注意しましょう。
require 'mime/types' path = '/home/keita/test.png' MIME::Types.type_for(path)[0].to_s # => "image/png"
なおMIME::Typeクラスには encoding, binary?, ascii?, simplified などの微妙に便利そうなメソッドが用意されています。また新たな型を簡単に追加できますので、場合によっては便利だと思います。
shared-mime-infoライブラリ
クラスMIMEのクラスメソッド check/check_globs/check_magics を用いて判別を行ないます。返り値は MIME::Type オブジェクトです。
require 'shared-mime-info' path = '/home/keita/test.png' MIME.check(path) # ファイル名かファイル内容から判別する MIME.check_globs(path) # ファイル名から MIME.check_magics(path) # ファイル内容から
MIME::Typeオブジェクトにはメソッド comment がありますが、これは shared-mime-infoデータベースに登録されている説明文を返します。この説明文は各国語に訳されているので非常に便利そうです。
判別速度の比較
簡単に判別速度を比較しておくことにします。以下のスクリプトをつかって計測してみます。
require 'benchmark' require 'rubygems' require 'mime/types' M1 = MIME require 'shared-mime-info' M2 = MIME $path = "/home/keita/test.png" $n = 1000 Benchmark.bm do |job| job.report {$n.times do; M1::Types.type_for($path); end} job.report {$n.times do; M2.check($path); end} job.report {$n.times do; M2.check_globs($path); end} job.report {$n.times do; M2.check_magics($path); end} end
私の環境での実行結果は以下のようになりました。
user system total real 0.010000 0.000000 0.010000 ( 0.016317) 1.700000 0.220000 1.920000 ( 2.036679) 1.440000 0.230000 1.670000 ( 1.897744) 2.790000 0.430000 3.220000 ( 3.521380)
よって、MIME::Typesライブラリの方が圧倒的に速いようです。