Determina il tipo di file in Ruby

Come si determina in modo affidabile il tipo di un file? L’analisi dell’estensione del file non è accettabile. Ci deve essere uno strumento rubyesque simile al comando UNIX file (1)?

Riguarda il MIME o il tipo di contenuto, non le classificazioni del file system, come directory, file o socket.

C’è un legame ruby con libmagic che fa ciò di cui hai bisogno. È disponibile come gem denominata ruby-filemagic :

 gem install ruby-filemagic 

Richiedi libmagic-dev .

La documentazione sembra un po ‘sottile, ma questo dovrebbe iniziare:

 $ irb irb(main):001:0> require 'filemagic' => true irb(main):002:0> fm = FileMagic.new => # irb(main):003:0> fm.file('foo.zip') => "Zip archive data, at least v2.0 to extract" irb(main):004:0> 

Se sei su una macchina Unix prova questo:

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

Non sono a conoscenza di soluzioni puramente Ruby che funzionano in modo affidabile come “file”.

Modificato per aggiungere: a seconda del sistema operativo in uso potrebbe essere necessario utilizzare ‘i’ anziché ‘I’ per ottenere il file per restituire un tipo mime.

Ho trovato il bombardamento per essere il più affidabile. Per compatibilità sia su Mac OS X che su Ubuntu Linux ho usato:

file --mime -b myvideo.mp4
video / mp4; charset = binario

Ubuntu stampa anche informazioni sui codec video se può essere abbastanza interessante:

file -b myvideo.mp4
ISO Media, sistema MPEG v4, versione 2

Puoi utilizzare questa affidabile base di metodi sull’intestazione magica del 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 

Se stai usando la class File, puoi aumentarla con le seguenti funzioni basate sulla risposta di @ 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 

E, se stai usando Ruby on Rails, puoi lasciarlo in config / initializers / file.rb e avere a disposizione tutto il tuo progetto.

Potresti provare a usare mime condiviso (gem install shared-mime-info). Richiede l’uso della libreria di mime-info condivisa di Freedesktop, ma controlla sia i nomi dei file / delle estensioni che i controlli “magici” … ho provato a darmi un vago io stesso ma ora non ho le informazioni mime condivise di freedesktop database installato e devo fare “lavoro vero”, sfortunatamente, ma potrebbe essere quello che stai cercando.

Soluzione Pure Ruby che utilizza i byte magici e restituisce un simbolo per il tipo corrispondente:

https://github.com/SixArm/sixarm_ruby_magic_number_type

L’ho scritto, quindi se hai dei suggerimenti, fammi sapere.

Recentemente ho trovato il mimetype-fu .

Sembra essere la soluzione più semplice e affidabile per ottenere il tipo MIME di un file.

L’unica avvertenza è che su una macchina Windows utilizza solo l’estensione del file, mentre su sistemi basati su * Nix funziona alla grande.

Per coloro che sono venuti qui dal motore di ricerca, un approccio moderno per trovare il MimeType in puro ruby è usare la gem mimetica .

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

Se ritieni che sia sicuro utilizzare solo l’estensione del file, puoi utilizzare la gem mime-types :

 MIME::Types.type_for('tux.jpg') => [#] 

Il meglio che ho trovato finora:

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

La gem ruby sta bene. mime-tipi per ruby

Potresti provare con MIME :: Types for Ruby .

Questa libreria consente l’identificazione del probabile tipo di contenuto MIME di un file. L’identificazione del tipo di contenuto MIME è basata sulle estensioni del nome file di un file.