在Ruby中检测上传文件的MIME类型

时间:2022-02-23 21:23:10

Is there a bullet proof way to detect MIME type of uploaded file in Ruby or Ruby on Rails? I'm uploading JPEGs and PNGs using SWFupload and content_type is always "application/octet-stream"

在Ruby或Ruby on Rails中有检测上传文件的MIME类型的有效方法吗?我用SWFupload上传jpeg和PNGs而content_type总是"application/octet-stream"

7 个解决方案

#1


43  

The ruby-filemagic gem will do it:

红宝石般的丝状宝石可以做到:

require 'filemagic'

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

This gem does not look at the file extension at all. It reads a bit of the file contents and uses that to guess the file's type.

此gem不查看文件扩展名。它读取一些文件内容并使用这些内容猜测文件的类型。

#2


36  

In Ruby on Rails you can do:

在Ruby on Rails中,你可以做到:

MIME::Types.type_for("filename.gif").first.content_type # => "image/gif"

#3


20  

You can use this reliable method base on the magic header of the file :

你可以使用这个可靠的方法基于魔术头的文件:

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


8  

The ruby-filemagic gem is good solution, but requires additional dependencies on libmagic (recently removed from CarrierWave as part of CarrierWave::MagicMimeTypes removal).

ruby-filemagic gem是一个很好的解决方案,但是需要对libmagic(最近作为CarrierWave的一部分从CarrierWave中删除::MagicMimeTypes removal)附加依赖。

If you're interested in a pure ruby implementation, consider the MimeMagic gem! It works well for file types listed in the freedesktop.org mime database:

如果您对纯ruby实现感兴趣,请考虑MimeMagic gem!它适用于freedesktop.org mime数据库中列出的文件类型:

require 'mimemagic'

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

For Microsoft Office 2007+ formats (xlsx, docx, and pptx), require the overlay (unless you're okay with the generic "application/zip" MIME type for these files)

对于Microsoft Office 2007+格式(xlsx、docx和pptx),需要覆盖(除非您对这些文件的通用“application/zip”MIME类型没有问题)

require 'mimemagic'    
require 'mimemagic/overlay'

MimeMagic.by_magic(File.open('big_spreadsheet.xlsx')).type # => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" 

#5


5  

filemagic gem is good solution but depends lots of unnecessary gems. (rails, aws-sdk-core, ...)

丝状宝石是一种很好的解决方案,但是需要大量不必要的宝石。(rails aws-sdk-core…)

If your app is small and only runs in Linux or OSX, consider to use file program:

如果你的应用程序很小,并且只在Linux或OSX上运行,考虑使用文件程序:

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

Note: Replace __FILE__ with any expr contains the filepath.

注意:用任何expr替换__FILE__包含filepath。

#6


3  

mimemagic gem will also do it

mimemagic gem也会这么做

https://github.com/minad/mimemagic

https://github.com/minad/mimemagic

from the oficial documentation

从oficial文档

MimeMagic is a library to detect the mime type of a file by extension or by content. It uses the mime database provided by freedesktop.org (see http://freedesktop.org/wiki/Software/shared-mime-info/).

MimeMagic是一个库,用于根据扩展名或内容检测文件的mime类型。它使用freedesktop.org提供的mime数据库(参见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...

#7


-4  

You can use

您可以使用

Mime::Type.lookup_by_extension(extention_name)

Mime:Type.lookup_by_extension(extention_name)

Thanks

谢谢

#1


43  

The ruby-filemagic gem will do it:

红宝石般的丝状宝石可以做到:

require 'filemagic'

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

This gem does not look at the file extension at all. It reads a bit of the file contents and uses that to guess the file's type.

此gem不查看文件扩展名。它读取一些文件内容并使用这些内容猜测文件的类型。

#2


36  

In Ruby on Rails you can do:

在Ruby on Rails中,你可以做到:

MIME::Types.type_for("filename.gif").first.content_type # => "image/gif"

#3


20  

You can use this reliable method base on the magic header of the file :

你可以使用这个可靠的方法基于魔术头的文件:

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


8  

The ruby-filemagic gem is good solution, but requires additional dependencies on libmagic (recently removed from CarrierWave as part of CarrierWave::MagicMimeTypes removal).

ruby-filemagic gem是一个很好的解决方案,但是需要对libmagic(最近作为CarrierWave的一部分从CarrierWave中删除::MagicMimeTypes removal)附加依赖。

If you're interested in a pure ruby implementation, consider the MimeMagic gem! It works well for file types listed in the freedesktop.org mime database:

如果您对纯ruby实现感兴趣,请考虑MimeMagic gem!它适用于freedesktop.org mime数据库中列出的文件类型:

require 'mimemagic'

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

For Microsoft Office 2007+ formats (xlsx, docx, and pptx), require the overlay (unless you're okay with the generic "application/zip" MIME type for these files)

对于Microsoft Office 2007+格式(xlsx、docx和pptx),需要覆盖(除非您对这些文件的通用“application/zip”MIME类型没有问题)

require 'mimemagic'    
require 'mimemagic/overlay'

MimeMagic.by_magic(File.open('big_spreadsheet.xlsx')).type # => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" 

#5


5  

filemagic gem is good solution but depends lots of unnecessary gems. (rails, aws-sdk-core, ...)

丝状宝石是一种很好的解决方案,但是需要大量不必要的宝石。(rails aws-sdk-core…)

If your app is small and only runs in Linux or OSX, consider to use file program:

如果你的应用程序很小,并且只在Linux或OSX上运行,考虑使用文件程序:

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

Note: Replace __FILE__ with any expr contains the filepath.

注意:用任何expr替换__FILE__包含filepath。

#6


3  

mimemagic gem will also do it

mimemagic gem也会这么做

https://github.com/minad/mimemagic

https://github.com/minad/mimemagic

from the oficial documentation

从oficial文档

MimeMagic is a library to detect the mime type of a file by extension or by content. It uses the mime database provided by freedesktop.org (see http://freedesktop.org/wiki/Software/shared-mime-info/).

MimeMagic是一个库,用于根据扩展名或内容检测文件的mime类型。它使用freedesktop.org提供的mime数据库(参见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...

#7


-4  

You can use

您可以使用

Mime::Type.lookup_by_extension(extention_name)

Mime:Type.lookup_by_extension(extention_name)

Thanks

谢谢

相关文章