Есть ли способ проверить, содержит ли переменная Ruby двоичные данные?

Я использую Ruby 2.4 и Rails 5. У меня есть содержимое файла в variabe с именем "content". Содержимое может содержать данные из таких вещей, как файл PDF, файл Word или файл HTML. Есть ли способ узнать, содержит ли переменная двоичные данные? В конечном счете, я хотел бы знать, является ли это файлом PDF, Microsoft Office или другим файлом OpenOffice. Этот ответ - Rails: можно проверить, является ли строка двоичной? - предполагает, что я могу проверить кодировку переменной

content.encoding

и он произведет

ASCII-8BIT

в случае двоичных данных, однако, я заметил, что есть случаи, когда содержимое HTML, хранящееся в переменной, также может возвращать "ASCII-8BIT" в качестве content.encoding, поэтому использование "content.encoding" не является надежный способ сказать мне, если у меня есть двоичные данные. Существует ли такой способ, и если да, то что это такое?

Ответ 1

Если ваш реальный вопрос касается не двоичных данных как таковых, а определения типа файла данных, я бы рекомендовал посмотреть ruby-filemagic gem, который даст вам эту информацию гораздо более надежно. Драгоценный камень - простая обертка вокруг библиотеки libmagic, которая является стандартной для unix-подобных систем. Библиотека работает, просматривая содержимое файла и сопоставляя его с набором известных "магических" шаблонов в разных типах файлов.

Пример использования для строкового буфера (например, чтение данных из базы данных):

require "ruby-filemagic"

content = File.read("/.../sample.pdf") # just an example to get some data

fm = FileMagic.new
fm.buffer(content)    
#=> "PDF document, version 1.4"

Для того, чтобы камень работал (и компилировался), вам нужна утилита file, а также библиотека magic с заголовками, установленными в вашей системе. Цитата из файла readme:

Требуется библиотека и заголовки файлов (1):

Debian/Ubuntu:: + libmagic-dev +
Fedora/SuSE:: + file-devel +
Gentoo:: + sys-libs/libmagic +
OS X:: brew установить libmagic

Протестировано, чтобы хорошо работать под Rails 5.

Ответ 2

Если вы используете Unix-машину, вы можете использовать команду file:

file titi.pdf

Затем вы можете сделать что-то вроде:

require 'open2'

cmd = 'file -'
Open3.popen3(cmd) do |stdin, stdout, wait_thr|
  stdin.write(content)
  stdin.close
  puts "file type is:" + stoud.read
end