Я должен проанализировать некоторые простые двоичные файлы. (Файлы содержат n записи, который состоит из нескольких / целых чисел без знака со знаком различных размеров и т.д.),
В момент я делаю парсинг "вручную". Кто-то знает библиотеку, которая помогает сделать этот тип парсинга?
Править: "Рукой" означает, что я добираюсь, Байт Данных Байтом сортируют его в к правильному порядку и преобразовывают его в Интервал/Байт И т.д. Также, некоторые Данные не подписаны.
Я использовал библиотеку sbinary раньше и это очень приятно. Документация немного скудна, но я бы посоветовал сначала взглянуть на старую вики-страницу , поскольку это дает вам отправную точку. Затем ознакомьтесь со спецификациями тестов, так как это дает вам несколько очень хороших примеров.
Основным преимуществом sbinary является то, что он дает вам способ описать формат связи каждого объекта как объект Format. Затем вы можете инкапсулировать эти форматированные типы в объект Format более высокого уровня, и Scala выполняет всю тяжелую работу по поиску этого типа, если вы включили его в текущую область как неявный объект.
Как я говорю ниже, я бы теперь рекомендовал людям использовать scodec вместо sbinary. В качестве примера использования scodec я реализую, как читать двоичное представление в памяти следующей структуры C:
struct ST
{
long long ll; // @ 0
int i; // @ 8
short s; // @ 12
char ch1; // @ 14
char ch2; // @ 15
} ST;
Соответствующим классом сценария Scala будет:
case class ST(ll: Long, i: Int, s: Short, ch1: String, ch2: String)
Я немного упрощаю задачу для я просто сказал, что мы храним строки вместо символов, и я скажу, что это символы UTF-8 в структуре. Я также не занимаюсь подробностями порядка байтов или фактическим размером типов long и 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)
Затем мы можем преобразовать его в класс случая ST, вызвав на нем функцию xmap
, которая принимает две функции, одна для превращения кодека Tuple в место назначения. type и другую функцию, чтобы взять целевой тип и преобразовать его в форму 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, а не на Guide, поскольку там гораздо подробнее в Scaladocs. Руководство - хорошее начало с самых основ, но оно не особо касается части композиции, но Scaladocs это довольно хорошо охватывает.
Я не знаю, что вы имеете в виду под словом «вручную», но использую простой DataInputStream
(apidoc здесь ) довольно краток и ясен:
val dis = new DataInputStream(yourSource)
dis.readFloat()
dis.readDouble()
dis.readInt()
// and so on
Взято из другого вопроса SO : http://preon.sourceforge.net/ , это должна быть структура для двоичного кодирования / декодирование ... посмотрите, есть ли у него необходимые вам возможности
Сам Scala не имеет библиотеки ввода двоичных данных, но пакет java.nio
неплохо справляется. Он не обрабатывает беззнаковые данные явно, как и Java, поэтому вам нужно выяснить, как вы хотите ими управлять, но у него есть удобные методы «get», которые учитывают порядок байтов.
Если вы ищете решение на основе Java, то я бессовестно вставлю Preon. Вы просто аннотируете структуру данных Java в памяти, запрашиваете у Preon кодек, и все готово.