Search code examples
ruby-on-railsfileruby-on-rails-5mime-typesfile-type

How do I reliably determine file type when FileMagic is not an option?


I'm using Rails 5.0.3. How do I reliably determine file type (this is from a file on my computer, not one I just downloaded from the Internet) without relying on file extensions? I would like a cross-platform way to do this only because I'm using Mac for development and Linux for test/prod. Also, the gem file magic is not an option because of this error

Bundler could not find compatible versions for gem "rails":
  In Gemfile:
    rails (~> 5.0.1)

    filemagic was resolved to 0.3.5.0, which depends on
      rails (< 5, >= 4.2.0)

Solution

  • filemagic isn't the gem you're looking for. This appears to be someone's project not intended for public consumption (the rubygems page links to a company's website, and no source code is available).

    Instead, install the ruby-filemagic gem. Here's the source and documentation. We can use the library like so:

    begin
      fm = FileMagic.new(FileMagic::MAGIC_MIME)
      puts fm.file("foo.txt", true)
    ensure
      fm.close
    end
    

    ...or by using the open() helper method, which automatically closes the resource for us:

    FileMagic.open(FileMagic::MAGIC_MIME) { |fm| puts fm.file("foo.txt", true) }
    

    This also works with yet another helper, mime(), which additionally sets the flag for us:

    FileMagic.mime { |fm| puts fm.file("foo.txt", true) }
    

    This gem relies on libmagic, a library used to identify file types using the file's magic number. The file command, commonly found on Unix/Linux systems, uses the same library:

    $ file --mime-type foo.txt
    foo.txt: text/plain
    

    We can also invoke this command from the Ruby application to get a file's MIME type:

    IO.popen(["file", "--mime-type", "--brief", "foo.txt"]) { |io| puts io.read.chomp }
    

    MimeMagic is an alternative to FileMagic.