Определить MIME-тип загруженного файла в Ruby - PullRequest
43 голосов
/ 05 января 2011

Существует ли пуленепробиваемый способ определения типа загруженного файла MIME в Ruby или Ruby on Rails? Я загружаю JPEG и PNG с помощью SWFupload и content_type всегда "application/octet-stream"

Ответы [ 7 ]

46 голосов
/ 05 января 2011

Gem ruby-filemagic сделает это:

require 'filemagic'

puts FileMagic.new(FileMagic::MAGIC_MIME).file(__FILE__)
# => text/x-ruby; charset=us-ascii

Этот драгоценный камень не смотрит на расширение файла вообще. Он читает немного содержимого файла и использует его, чтобы угадать тип файла.

38 голосов
/ 24 сентября 2011

В Ruby on Rails вы можете сделать:

MIME::Types.type_for("filename.gif").first.content_type # => "image/gif"
21 голосов
/ 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
11 голосов
/ 11 мая 2016

Драгоценный камень ruby-filemagic является хорошим решением, но требует дополнительных зависимостей от libmagic (недавно удален из CarrierWave как часть удаления CarrierWave :: MagicMimeTypes ).

Если вы заинтересованы в реализации в чистом рубине, рассмотрите гем MimeMagic ! Он хорошо работает для типов файлов, перечисленных в базе данных mime freedesktop.org:

require 'mimemagic'

MimeMagic.by_magic(File.open('Table-Flip-Guy.jpg')).type # => "image/jpeg" 

Для форматов Microsoft Office 2007+ (xlsx, docx и pptx) требуется наложение (если вы не согласны с универсальным типом MIME "application / zip" для этих файлов)

require 'mimemagic'    
require 'mimemagic/overlay'

MimeMagic.by_magic(File.open('big_spreadsheet.xlsx')).type # => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" 
6 голосов
/ 23 апреля 2017

filemagic gem - хорошее решение, но зависит от множества ненужных самоцветов. (рельсы, aws-sdk-core, ...)

Если ваше приложение маленькое и работает только в Linux или OSX, рассмотрите возможность использования file программы:

require 'shellwords'
mimetype = `file --brief --mime-type - < #{Shellwords.shellescape(__FILE__)}`.strip

Примечание. Замените __FILE__ на любой expr, содержащий путь к файлу.

4 голосов
/ 09 июня 2016

mimemagic gem также сделает это

https://github.com/minad/mimemagic

из официальной документации

MimeMagic - это библиотека для определения типа mime файла порасширение или по содержанию.Он использует базу данных MIME, предоставленную freedesktop.org (см. http://freedesktop.org/wiki/Software/shared-mime-info/).

require 'mimemagic'
MimeMagic.by_extension('html').text?
MimeMagic.by_extension('.html').child_of? 'text/plain'
MimeMagic.by_path('filename.txt')
MimeMagic.by_magic(File.open('test.html'))
# etc...
0 голосов
/ 24 сентября 2013

Вы можете использовать

Mime :: Type.lookup_by_extension (extention_name)

Спасибо

...