Определить тип файла в Ruby - PullRequest
67 голосов
/ 09 сентября 2008

Как один надежно определяет тип файла? Анализ расширений файлов недопустим. Должен быть инструмент rubyesque, аналогичный команде UNIX file (1)?

Это касается MIME или типа контента, а не классификации файловой системы, такой как каталог, файл или сокет.

Ответы [ 12 ]

58 голосов
/ 23 мая 2009

Существует рубиновая привязка к 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> 
33 голосов
/ 11 сентября 2008

Если вы работаете на Unix-машине, попробуйте это:

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

Мне неизвестны какие-либо чистые решения на Ruby, которые работают так же надежно, как «файл».

Отредактировано для добавления: в зависимости от того, какую операционную систему вы используете, вам может понадобиться использовать «i» вместо «I», чтобы получить файл для возврата mime-типа.

13 голосов
/ 07 ноября 2010

Я считаю обстрел самым надежным. Для совместимости на Mac OS X и Ubuntu Linux я использовал:

file --mime -b myvideo.mp4
видео / mp4; кодировка = двоичный

Ubuntu также печатает информацию о видеокодеках, если это возможно, что довольно круто:

file -b myvideo.mp4
Носитель ISO, система MPEG v4, версия 2

8 голосов
/ 19 мая 2013

Вы можете использовать этот надежный метод на основе магического заголовка файла:

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
5 голосов
/ 17 сентября 2014

Если вы используете класс 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 и получить доступ к нему по всему проекту.

2 голосов
/ 18 сентября 2008

Вы можете попробовать shared-mime (gem install shared-mime-info). Требует использования библиотеки shared-mime-info Freedesktop, но выполняет как проверки имени файла / расширения, так и проверки «магии» ... я пытался сделать это сейчас, но у меня нет freedesktop shared-mime-info База данных установлена ​​и, к сожалению, должна выполнять «реальную работу», но это может быть то, что вы ищете.

1 голос
/ 10 мая 2018

Для тех, кто пришел сюда с помощью поисковой системы, современный подход к поиску MimeType в чистом рубине - это использование mimemagic gem.

require 'mimemagic'

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

Если вы считаете безопасным использование только расширения файла, вы можете использовать mime-types gem:

MIME::Types.type_for('tux.jpg') => [#<MIME::Type: image/jpeg>]
1 голос
/ 21 апреля 2012

Чистое решение Ruby с использованием магических байтов и возвращением символа для соответствующего типа:

https://github.com/SixArm/sixarm_ruby_magic_number_type

Я написал это, так что если у вас есть предложения, дайте мне знать.

1 голос
/ 20 сентября 2010

Я недавно нашел mimetype-fu .

Кажется, это самое простое и надежное решение для получения файла MIME-типа.

Единственное предостережение в том, что на машине с Windows он использует только расширение файла, тогда как на * Nix-системах он отлично работает.

0 голосов
/ 25 января 2012

Лучшее, что я нашел до сих пор:

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

...