确定Ruby中的文件类型

时间:2008-09-09 10:46:51

标签: ruby content-type mime-types file-type

如何可靠确定文件的类型?文件扩展名分析是不可接受的。必须有类似于UNIX file(1)命令的rubyesque工具吗?

这是关于MIME或内容类型,而不是文件系统分类,例如目录,文件或套接字。

13 个答案:

答案 0 :(得分:58)

libmagic的红宝石绑定可以满足你的需要。它可以作为名为ruby-filemagic的宝石使用:

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> 

答案 1 :(得分:33)

如果你在Unix机器上试试这个:

mimetype = `file -Ib #{path}`.gsub(/\n/,"")

我不知道任何纯粹的Ruby解决方案与'file'一样可靠。

编辑添加:根据您运行的操作系统,您可能需要使用“i”代替“I”来获取文件以返回mime类型。

答案 2 :(得分:13)

我发现炮击是最可靠的。为了兼容Mac OS X和Ubuntu Linux,我使用了:

file --mime -b myvideo.mp4
视频/ MP4;字符集=二进制

Ubuntu还可以打印视频编解码器信息,如果它非常酷的话:

file -b myvideo.mp4
ISO Media,MPEG v4系统,版本2

答案 3 :(得分:8)

您可以根据文件的魔术标头使用这种可靠的方法:

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

答案 4 :(得分:5)

如果你正在使用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并在整个项目中使用。

答案 5 :(得分:2)

您可以尝试shared-mime(gem install shared-mime-info)。需要使用Freedesktop shared-mime-info库,但同时进行文件名/扩展名检查以及“魔术”检查......我试着让它自己动起来但我没有freedesktop shared-mime-info不幸的是,数据库安装并且必须做“真正的工作”,但它可能正是你正在寻找的。

答案 6 :(得分:1)

我最近找到了mimetype-fu

这似乎是获取文件MIME类型的最简单可靠的解决方案。

唯一需要注意的是,在Windows机器上它只使用文件扩展名,而在基于* Nix的系统上它运行良好。

答案 7 :(得分:1)

纯Ruby解决方案使用魔术字节并返回匹配类型的符号:

https://github.com/SixArm/sixarm_ruby_magic_number_type

我写了,所以如果你有建议,请告诉我。

答案 8 :(得分:1)

对于那些通过搜索引擎来到这里的人来说,在纯红宝石中找到MimeType的现代方法是使用Julien's Answer gem。

require 'mimemagic'

MimeMagic.by_magic(File.open('tux.jpg')).type # => "image/jpeg" 

如果您觉得仅使用文件扩展名是安全的,那么您可以使用mimemagic gem:

MIME::Types.type_for('tux.jpg') => [#<MIME::Type: image/jpeg>]

答案 9 :(得分:1)

这是对this answer的评论,但实际上应该是它自己的答案:

path = # path to your file

IO.popen(
  ["file", "--brief", "--mime-type", path],
  in: :close, err: :close
) { |io| io.read.chomp }

我可以确认它对我有用。

答案 10 :(得分:0)

到目前为止我发现的最好:

http://bogomips.org/mahoro.git/

答案 11 :(得分:-1)

红宝石宝石很好。 mime-types for ruby

答案 12 :(得分:-2)

你可以放手MIME::Types for Ruby

  

此库允许识别文件可能的MIME内容类型。 MIME内容类型的标识基于文件的文件扩展名。