2011-01-05 147 views

回答

42

ruby-filemagic創業板將做到這一點:

require 'filemagic' 

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

這種寶石沒有文件擴展名,看看所有。它讀取一些文件內容並使用它來猜測文件的類型。

+8

在OS X上,我只需要在'gem install ruby​​-filemagic'工作前'brew install libmagic'。但寶石的作品像圖像/ PNG,圖像/ jpg,應用程序/ x-shockwave-flash,視頻/ mp4,應用程序/ ogg,圖像/ vnd.adobe.photoshop,應用程序/ pdf,視頻/ x-ms- asf等 – 2014-06-21 16:59:50

+1

如果你在Ubuntu上,apt-get install libmagic-dev。 – wpp 2014-11-19 08:57:13

+0

只是爲了澄清(與@NARKOZ的答案對比),這個gem並不尋找擴展名來尋找MIME類型,不像rails的MIME :: types選項。 – alexanderbird 2015-06-12 22:42:01

35

在Ruby on Rails的,你可以這樣做:

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

>根據文件擴展名返回屬於該文件的MIME :: Types的列表。如果平臺爲真,那麼只返回特定於當前平臺的文件類型。 – knoopx 2011-09-26 11:48:31

+27

不是有效答案,它只是根據擴展名檢測文件類型。如果你命名一個FLV擴展的PNG文件,它會檢測到它是一個=>「video/x-flv」 – 2012-10-01 13:06:25

+9

如果你強制執行一致的文件擴展名,可能會足夠好。 – 2013-02-11 12:29:53

19

你可以使用這個可靠的方法基礎上的文件的魔法頭:

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 
+8

在反引號中運行外部命令時使用字符串插值通常不是一個好主意。 'local_file_path'可以設置爲'; rm -rf .'。在這種特殊情況下,該方法可以在不擦除當前目錄的情況下安全地通過'Errno :: ENOENT'失敗,但當用戶提供文件名時,最好不要依賴該方法。 – rekado 2013-06-07 01:25:57

-4

您可以使用

MIME類型: :Type.lookup_by_extension(extention_name)

謝謝

+5

由於擴展與實際文件類型無關,因此被降級。可能沒有擴展名。 – panzi 2014-03-12 23:57:42

+0

如果您強制執行一致的文件擴展名,可能會不夠好。 – NARKOZ 2014-03-20 12:20:48

+1

-1,因爲這延續了文件擴展名與文件類型相關的信念(Windows是唯一準確的地方)。 – Dan 2014-05-12 16:50:19

5

紅寶石filemagic寶石是很好的解決方案,但是需要額外的依賴於libmagic(最近從CarrierWave除去的CarrierWave :: MagicMimeTypes去除一部分)。

如果您對純粹的ruby實現感興趣,請考慮MimeMagic寶石!它非常適用於freedesktop.org的MIME數據庫中列出的文件類型:

require 'mimemagic' 

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

對於Microsoft Office 2007+格式(XLSX,DOCX,PPTX和),需要覆蓋(除非你沒事用通用的「應用程序/壓縮」,從公報資料MIME類型,這些文件)

require 'mimemagic'  
require 'mimemagic/overlay' 

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

mimemagic寶石也將做到這一點

https://github.com/minad/mimemagic

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... 
1

filemagic gem是很好的解決方案,但依賴於大量不必要的寶石。 (導軌,AWS-SDK核心,...)

如果您的應用程序小,只在Linux或OSX上運行,可考慮使用file程序:

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

注:與任何EXPR替換__FILE__包含文件路徑。

相關問題