Анализ двоичных данных с помощью scala

Мне нужно разобрать несколько простых двоичных файлов. (Файлы содержат n записей, которые состоят из нескольких подписанных/неподписанных целых чисел разных размеров и т.д.)

В тот момент, когда я разбираю "вручную". Кто-нибудь знает библиотеку, которая помогает выполнять этот тип разбора?

Изменить: "По руке" означает, что я получаю байт данных by Byte, сортируя его в правильном порядке и преобразовывая его в Int/Byte и т.д. Также некоторые из данных без знака.

Ответы

Ответ 1

Я использовал библиотеку sbinary, и это очень приятно. Документация немного редка, но я бы предложил сначала посмотреть на старую страницу wiki, поскольку это дает вам отправную точку. Затем проверьте спецификации теста, так как это дает вам несколько хороших примеров.

Основное преимущество sbinary заключается в том, что он дает вам способ описать формат проводов для каждого объекта в качестве объекта Format. Затем вы можете инкапсулировать эти форматированные типы в объект формата более высокого уровня, а Scala выполняет весь тяжелый подъем этого типа до тех пор, пока вы включили его в текущую область как неявный объект.

Как я уже сказал ниже, теперь я рекомендую использовать scodec вместо sbinary. В качестве примера использования scodec я буду реализовывать, как читать двоичное представление в памяти следующей C struct:

struct ST
{
   long long ll; // @ 0
   int i;        // @ 8
   short s;      // @ 12
   char ch1;     // @ 14
   char ch2;     // @ 15
} ST;

Соответствующий класс case Scala:

case class ST(ll: Long, i: Int, s: Short, ch1: String, ch2: String)

Я делаю вещи немного легче для себя, просто говоря, что мы храним Strings вместо Chars, и я скажу, что они являются символами UTF-8 в структуре. Я также не имею дело с деталями endian или фактическим размером длинного и int-типа в этой архитектуре и просто предполагаю, что они равны соответственно 64 и 32.

Анализаторы Scodec обычно используют комбинаторы для создания парсеров более высокого уровня с более низких уровней. Итак, ниже мы определим синтаксический анализатор, который объединяет 8-байтовое значение, значение 4 байта, значение 2 байта, значение 1 байт и еще одно значение в 1 байт. Возврат этой комбинации является кодеком Tuple:

val myCodec: Codec[Long ~ Int ~ Short ~ String ~ String] = 
  int64 ~ int32 ~ short16 ~ fixedSizeBits(8L, utf8) ~ fixedSizeBits(8L, utf8)

Затем мы можем преобразовать это в класс case ST, вызвав на нем функцию xmap, которая принимает две функции: одну, чтобы превратить кодек Tuple в тип назначения и другую функцию, чтобы взять тип назначения и превратить его в Форма кортежа:

val stCodec: Codec[ST] = myCodec.xmap[ST]({case ll ~ i ~ s ~ ch1 ~ ch2 => ST(ll, i, s, ch1, ch2)}, st => st.ll ~ st.i ~ st.s ~ st.ch1 ~ st.ch2)

Теперь вы можете использовать кодек так:

stCodec.encode(ST(1L, 2, 3.shortValue, "H", "I"))
res0: scodec.Attempt[scodec.bits.BitVector] = Successful(BitVector(128 bits, 0x00000000000000010000000200034849))

res0.flatMap(stCodec.decode)
=> res1: scodec.Attempt[scodec.DecodeResult[ST]] = Successful(DecodeResult(ST(1,2,3,H,I),BitVector(empty)))

Я бы посоветовал вам взглянуть на Scaladocs, а не на Руководство, так как в Scaladocs гораздо больше деталей. Руководство - это хорошее начало в самых основах, но оно не входит в состав композиции, но Scaladocs довольно хорошо обходятся.

Ответ 2

Я не знаю, что вы имеете в виду "вручную", но с помощью простого DataInputStream (apidoc здесь) довольно кратким и ясно:

val dis = new DataInputStream(yourSource)

dis.readFloat()
dis.readDouble()
dis.readInt()
// and so on

Взято из другого SO question: http://preon.sourceforge.net/, это должен быть каркасом для выполнения двоичного кодирования/декодирования.. см., есть ли у него необходимые возможности

Ответ 3

Scala сам не имеет библиотеки ввода двоичных данных, но пакет java.nio выполняет достойную работу. Он явно не обрабатывает неподписанные данные - и Java, поэтому вам нужно выяснить, как вы хотите управлять им, - но у него есть удобные методы "get", которые учитывают порядок байтов.

Ответ 4

Если вы ищете решение на базе Java, я буду бесстыдно подключать Preon. Вы просто комментируете структуру данных Java в памяти и задаете Preon для Codec, и все готово.

Ответ 5

Byteme является библиотекой компиляторов парсеров для выполнения двоичных файлов. Вы можете попробовать использовать его для своих задач.