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

发布于 2024-10-10 06:07:13 字数 158 浏览 4 评论 0 原文

是否有一种万无一失的方法可以在 Ruby 或 Ruby on Rails 中检测上传文件的 MIME 类型?我使用 SWFupload 上传 JPEG 和 PNG,content_type 始终为 "application/octet-stream"

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"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

泪之魂 2024-10-17 06:07:13

ruby-filemagic gem 可以做到这一点:

require 'filemagic'

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

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

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.

唯憾梦倾城 2024-10-17 06:07:13

在 Ruby on Rails 中,您可以执行以下操作:

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

In Ruby on Rails you can do:

MIME::Types.type_for("filename.gif").first.content_type # => "image/gif"
美人如玉 2024-10-17 06:07:13

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

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

require 'mimemagic'

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

对于 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" 

The ruby-filemagic gem is good solution, but requires additional dependencies on libmagic (recently removed from CarrierWave as part of 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:

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)

require 'mimemagic'    
require 'mimemagic/overlay'

MimeMagic.by_magic(File.open('big_spreadsheet.xlsx')).type # => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" 
九八野马 2024-10-17 06:07:13

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

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

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
浅浅 2024-10-17 06:07:13

截至 2021 年,我认为根据所有可用提示(幻数、幻数不够时的文件名、用户提示)计算 mime 类型的最佳工具是 马塞尔

无耻地引用文档本身:

Marcel::MimeType.for Pathname.new("example.gif")
#  => "image/gif"

File.open "example.gif" do |file|
  Marcel::MimeType.for file
end
#  => "image/gif"

Marcel::MimeType.for Pathname.new("unrecognisable-data"), name: "example.pdf"
#  => "application/pdf"

Marcel::MimeType.for extension: ".pdf"
#  => "application/pdf"

Marcel::MimeType.for Pathname.new("unrecognisable-data"), name: "example", declared_type: "image/png"
#  => "image/png"

Marcel::MimeType.for StringIO.new(File.read "unrecognisable-data")
#  => "application/octet-stream"

As of 2021, I would claim that the best tool to compute mime types based on all the available hints (magic number, file name when the magic number does not suffice, user hints) is Marcel.

To shamelessly quote the documentation itself:

Marcel::MimeType.for Pathname.new("example.gif")
#  => "image/gif"

File.open "example.gif" do |file|
  Marcel::MimeType.for file
end
#  => "image/gif"

Marcel::MimeType.for Pathname.new("unrecognisable-data"), name: "example.pdf"
#  => "application/pdf"

Marcel::MimeType.for extension: ".pdf"
#  => "application/pdf"

Marcel::MimeType.for Pathname.new("unrecognisable-data"), name: "example", declared_type: "image/png"
#  => "image/png"

Marcel::MimeType.for StringIO.new(File.read "unrecognisable-data")
#  => "application/octet-stream"
居里长安 2024-10-17 06:07:13

filemagic gem 是一个很好的解决方案,但依赖于许多不必要的 gem。 (rails、aws-sdk-core、...)

如果您的应用程序很小且仅在 Linux 或 OSX 中运行,请考虑使用 file 程序:

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

注意:替换 __FILE__任何 expr 都包含文件路径。

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

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

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

Note: Replace __FILE__ with any expr contains the filepath.

可爱暴击 2024-10-17 06:07:13

mimemagic gem 也会

做到https://github.com/minad/mimemagic

从官方文档中

MimeMagic 是一个通过扩展名检测文件 mime 类型的库
或按内容。它使用 freedesktop.org 提供的 mime 数据库
(请参阅http://freedesktop.org/wiki/Software/shared-mime-info/ )。

需要“mimemagic”
MimeMagic.by_extension('html').text?
MimeMagic.by_extension('.html').child_of? '文本/纯文本'
MimeMagic.by_path('文件名.txt')
MimeMagic.by_magic(File.open('test.html'))
# ETC...

mimemagic gem will also do it

https://github.com/minad/mimemagic

from the oficial documentation

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/).

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...
青柠芒果 2024-10-17 06:07:13

如果您从头开始执行此操作,请安装 mimemagic gem

gem 'mimemagic'

打开流(目标图像的字节),

url="https://i.ebayimg.com/images/g/rbIAAOSwojpgyQz1/s-l500.jpg"
result = URI.parse(url).open

然后检查数据流的文件类型,例如:

MimeMagic.by_magic(result) .type == "image/jpeg"

即使如上所述

%w(JPEG GIF TIFF PNG).include?(MimeMagic.by_magic(result).type)

这可能更多优雅的

in case you are doing this from scratch, install mimemagic gem

gem 'mimemagic'

open stream(bytes of target image)

url="https://i.ebayimg.com/images/g/rbIAAOSwojpgyQz1/s-l500.jpg"
result = URI.parse(url).open

then check data-stream's file type for example:

MimeMagic.by_magic(result).type == "image/jpeg"

even though as mentioned above

%w(JPEG GIF TIFF PNG).include?(MimeMagic.by_magic(result).type)

this might be more elegant

失退 2024-10-17 06:07:13

您可以使用

Mime::Type.lookup_by_extension(extention_name)

谢谢

You can use

Mime::Type.lookup_by_extension(extention_name)

Thanks

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文