在Ruby中确定文件types
如何可靠地确定一个文件的types? 文件扩展名分析是不可接受的。 必须有一个类似UNIX文件(1)命令的rubyesque工具?
这是关于MIME或内容types,而不是文件系统分类,如目录,文件或套接字。
有一个ruby绑定到libmagic
做你所需要的。 它是一个名为ruby-filemagic的gem:
gem install ruby-filemagic
需要libmagic-dev
。
文档看起来有点薄,但这应该让你开始:
$ irb irb(main):001:0> require 'filemagic' => true irb(main):002:0> fm = FileMagic.new => #<FileMagic:0x7fd4afb0> irb(main):003:0> fm.file('foo.zip') => "Zip archive data, at least v2.0 to extract" irb(main):004:0>
如果你在Unix机器上,试试这个:
mimetype = `file -Ib #{path}`.gsub(/\n/,"")
我没有意识到任何纯粹的Ruby解决scheme和'file'一样可靠。
编辑添加:取决于你正在运行的操作系统,你可能需要使用'我'而不是'我'来获取文件返回一个MIMEtypes。
我发现炮轰是最可靠的。 为了兼容Mac OS X和Ubuntu Linux,我使用了:
file --mime -b myvideo.mp4
video/ MP4; 字符集=二进制
如果可以的话,Ubuntu也打印video编解码信息,这很酷:
file -b myvideo.mp4
ISO媒体,MPEG v4系统,版本2
您可以使用这个可靠的方法基于该文件的魔术标题:
def get_image_extension(local_file_path) png = Regexp.new("\x89PNG".force_encoding("binary")) jpg = Regexp.new("\xff\xd8\xff\xe0\x00\x10JFIF".force_encoding("binary")) jpg2 = Regexp.new("\xff\xd8\xff\xe1(.*){2}Exif".force_encoding("binary")) case IO.read(local_file_path, 10) when /^GIF8/ 'gif' when /^#{png}/ 'png' when /^#{jpg}/ 'jpg' when /^#{jpg2}/ 'jpg' else mime_type = `file #{local_file_path} --mime-type`.gsub("\n", '') # Works on linux and mac raise UnprocessableEntity, "unknown file type" if !mime_type mime_type.split(':')[1].split('/')[1].gsub('x-', '').gsub(/jpeg/, 'jpg').gsub(/text/, 'txt').gsub(/x-/, '') end end
如果您使用的是File类,则可以使用基于@ PatrickRichie的答案的以下函数来扩充它:
class File def mime_type `file --brief --mime-type #{self.path}`.strip end def charset `file --brief --mime #{self.path}`.split(';').second.split('=').second.strip end end
而且,如果您使用的是Ruby on Rails,则可以将其放置到config / initializers / file.rb中,并在整个项目中都可用。
你可以试试共享模仿 (gem install shared-mime-info)。 需要使用Freedesktop的共享MIME信息库,但既做文件名/扩展名检查,也做“魔术”检查…试着给自己一个旋风,但我没有freedesktop共享MIME信息数据库安装,不得不做“真正的工作”,但不幸的是,它可能是你在找什么。
纯Ruby解决scheme使用魔术字节并返回匹配types的符号:
https://github.com/SixArm/sixarm_ruby_magic_number_type
我写了,所以如果你有build议,让我知道。
我最近发现mimetype-fu 。
这似乎是获得文件的MIMEtypes的最简单可靠的解决scheme。
唯一需要注意的是,在Windows机器上,它只使用文件扩展名,而在基于Nix的系统上则效果很好。
迄今为止我发现的最好的:
ruby很好。 哑剧式的ruby
您可以使用Ruby的MIME :: Types 。
这个库允许识别一个文件的可能的MIME内容types。 MIME内容types的标识基于文件的文件扩展名。