Модератор
2558 / 1094 / 375
Регистрация: 11.08.2017
Сообщений: 3,332
|
||||||||||||||||
1 | ||||||||||||||||
Сохранение бинарного json07.11.2019, 13:46. Показов 2400. Ответов 18
В гугле по поиску binary json или simple json java ничего не смог найти. Поэтому прошу помощи здесь.
Копаюсь в игре с редактором уровней, игра сохраняет файлы из редактора в сжатые бинарные джейсоны. Прочитать из бинарного файла в джейсон объект труда не возникло. Но теперь необходимо обратно записать объект в файл. Приложу мой класс чтения из файла для критики.
По сути надо обойти все json объекты углубляясь внутрь попутно записывая их последовательно в файл. Вот как это сделать не могу придумать. Ведь надо получить не только имена но и количество объектов на каждом уровне. На примере простого json
тэг 1 байт - 2 - объект json количество объектов 4 байта - 2 имя объекта 12 байт - (1байт размер имени + строка environment) тэг 1 байт - 4 - число инт число инт 4 байта - 1 имя объекта 5 байт - (1байт размер имени + строка size) тэг 1 байт - 4 - число инт число инт 4 байта - 1 На примере более сложного json
количество объектов 4 байта - 2 имя объекта 12 байт - (1байт размер имени + строка environment) тэг 1 байт - 2 - объект json количество объектов 4 байта - 2 имя объекта 12 байт - (1байт размер имени + строка environment) тэг 1 байт - 4 - число инт число инт 4 байта - 1 имя объекта 5 байт - (1байт размер имени + строка size) тэг 1 байт - 4 - число инт число инт 4 байта - 1 имя объекта 5 байт - (1байт размер имени + строка size) тэг 1 байт - 4 - число инт число инт 4 байта - 1
0
|
07.11.2019, 13:46 | |
Ответы с готовыми решениями:
18
Сохранение map в json Редактирование и сохранение изменений в файл JSON [JSON] Правильное сохранение настроек в Json файл (Сохранение и чтение с бинарного файла) |
Модератор
2558 / 1094 / 375
Регистрация: 11.08.2017
Сообщений: 3,332
|
|
07.11.2019, 13:55 [ТС] | 2 |
ПЫСЫ ВСе это надо для того чтобы иметь возможность открывать в редакторе чужие карты, без правки файла карта грузится в режиме только для игры для не владельца файла. Если прописать себя в json то редактор спокойно открывает
0
|
3639 / 2971 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
|
|
07.11.2019, 14:15 | 3 |
в чем проблема то, я так и не понял?
0
|
Модератор
2558 / 1094 / 375
Регистрация: 11.08.2017
Сообщений: 3,332
|
|
07.11.2019, 14:22 [ТС] | 4 |
У меня нет идей как сохранить файл в бинарном формате
0
|
3639 / 2971 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
|
|
07.11.2019, 14:33 | 5 |
Раз ты знаешь, как читать, ты, видимо, знаешь формат файла. А раз так - берешь и пишешь.
0
|
Модератор
2558 / 1094 / 375
Регистрация: 11.08.2017
Сообщений: 3,332
|
||||||
07.11.2019, 22:19 [ТС] | 6 | |||||
Почти написал сохранение, но возникла пара непоняток.
Первое. Как узнать тип числа из JsonElement? Я проверяю его сначала на JsonPrimitive а потом примитив на isNumber а что дальше хз. Мне нужно определить что за тип числа из трех нужных: int, double и float. То есть после проверок я точно знаю что имею дело с числом но неизвестного типа. Тип (один из трех) необходим обязательно. И второе. Как нормально перевести число в тип int кодированный группами по 7 бит? Пару слов про это кодирование. Изначально берется число типа int и его надо перевести в группу из n беззнаковых 7 битных byte, после этого записать в файл начиная с младших групп и первый бит в каждой группе установить в 1 если есть еще группа и 0 если группа последняя. У меня вышел вот такой кривой способ.
После определяю сколько надо добавить нулей для того чтобы длинна строки стала кратна 7. Далее создаю добавку из нулей нужной длинны и добавляю ее к строке. Потом делю строку на группы по 7 знаков в массив строк. И в конце прохожу массив строк с конца добавляя по 1 или 0 (0 к первому элементу) перевожу их обратно в int, потом в byte и пишу это дело в OutputStream. Только мне мое решение не нравится. Более коротко и красиво придумать не могу.
0
|
Модератор
2558 / 1094 / 375
Регистрация: 11.08.2017
Сообщений: 3,332
|
||||||
08.11.2019, 14:03 [ТС] | 7 | |||||
Дописал, выкладываю весь код (чтение и запись) на критику и что стоит подправить (помимо предыдущего моего сообщения)
0
|
4486 / 2721 / 485
Регистрация: 28.04.2012
Сообщений: 8,590
|
|||||||||||||||||||||
08.11.2019, 21:43 | 8 | ||||||||||||||||||||
Зачем мешать в одном классе чтение и запись? Лучше разнести по двум разным.
Магические числа нужно заменить числовыми константами с понятными именами.
0
|
Модератор
2558 / 1094 / 375
Регистрация: 11.08.2017
Сообщений: 3,332
|
|||||||||||
09.11.2019, 12:07 [ТС] | 9 | ||||||||||
Вот новый вариант. Заменил функцию по кодированию длинны строки, надеюсь она получше. Возник вопрос, в стрингбилдере можно прибавлять строку не справа а слева?
reader
0
|
3639 / 2971 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
|
|
09.11.2019, 12:36 | 10 |
Про enum слышал? А про try-with-resources? Serialize. Ещё можно стратегию прикрутить, например.
0
|
Модератор
2558 / 1094 / 375
Регистрация: 11.08.2017
Сообщений: 3,332
|
|||||||||||||||||||||
09.11.2019, 13:30 [ТС] | 11 | ||||||||||||||||||||
xoraxax, Про enum слышал, но тут с ним будет только лишние усложнения и код. Меня напрягает switch-case по этому самому enum и enum начинается с нуля. А точнее считать байт из файла и сравнить его с enum без усложнения структуры enum не вижу способов.
Зачем здесь try-with-resources? А про Serialize и стратегию вообще не в курсе. Метод для чтения за основу был взят метод из шарпа от юнити и там был enum, но enum такого вида
Метод
Добавлено через 1 минуту Причем это происходит после середины файла ближе к концу, но до конца еще минимум около четверти файла. Добавлено через 36 минут Убрал строчку
0
|
3639 / 2971 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
|
|
09.11.2019, 13:36 | 12 |
Ты можешь конечно делать все, что угодно, но тогда непонятно, зачем ты тут советы спрашиваешь
0
|
Модератор
2558 / 1094 / 375
Регистрация: 11.08.2017
Сообщений: 3,332
|
|||||||||||
09.11.2019, 13:48 [ТС] | 13 | ||||||||||
Переделал на вот это
reader
Остальные вопросы хочу услышать ответы, особенно про про Serialize и стратегию
0
|
3639 / 2971 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
|
|
09.11.2019, 16:18 | 14 |
вот это просто написано неправильно было
А про стратегию - надо прочитать, что такое стратегия и подумать, куда ее можно засунуть. Иначе ты опять скажешь, что и так норм. Еще кстати, попробуй свой код тестами покрыть. Может так понятнее будет.
0
|
4486 / 2721 / 485
Регистрация: 28.04.2012
Сообщений: 8,590
|
||||||||||||||||||||||||||||||||||||
09.11.2019, 22:48 | 15 | |||||||||||||||||||||||||||||||||||
Зачем создавать массив из одного байта?
new Byte(...).byteValue() ?А вообще, результаты вызовов всех вариантов методов InputStream.read нужно проверять. Почитай документацию.
Добавлено через 15 минут
0
|
Модератор
2558 / 1094 / 375
Регистрация: 11.08.2017
Сообщений: 3,332
|
|
09.11.2019, 22:52 [ТС] | 16 |
Из одного байта так как без массива write принимает int а не byte и боюсь запишет int (4 байта) вместо byte (1 байт)
А ведь же read возвращает число прочитанных байт в формате int а мне нужно значение прочитанного байта в виде числа Про new Byte… не усмотрел. Может есть вариант короче записать boolean в 1 байт в виде чисел 1 или 0? Проверка по типу int test = in.read(byte[]); а потом если test != len то кидать исключение? Добавлю кодировку, надеюсь с utf-8 и 1 буквой на 1 байт проблем не будет. Во всех тонкостях не разбираюсь, поэтому сюда код на критику и выложил.
0
|
4486 / 2721 / 485
Регистрация: 28.04.2012
Сообщений: 8,590
|
|
09.11.2019, 23:25 | 17 |
Тут погорячился.
Добавлено через 2 минуты А ты вместо того, чтобы бояться, документацию б почитал. Конечно будет. В UTF-8 может быть больше одного байта на букву. Добавлено через 1 минуту Я вообще не понимаю, что там за адовая магия с чтением/записью строк происходит.
0
|
Модератор
2558 / 1094 / 375
Регистрация: 11.08.2017
Сообщений: 3,332
|
|||||||||||
10.11.2019, 13:26 [ТС] | 18 | ||||||||||
korvin_, Там происходит по сути вот что. Строка из себя представляет конструкцию из <размер строки в байтах><строка в виде байт>. Так вот этот размер надо получить и записать либо правильно прочитать. Размер там имеет нефиксированную длину от 1 до 5 байт (так как int занимает 4 байта). Суть описана тут, но там в примере порядок байт другой.
Лучше всего объяснит что происходит картинка во вложении, за исключением что байты идут в другом порядке, а следовательно выделенные байты другие. Там результат 10000110-11000011-00010111 А тут надо вот так 10010111-11000011-00000110 На сколько понимаю в примере на вики используется BIG_ENDIAN для разбивки числа на группы и приписке MSB, а у меня LITTLE_ENDIAN Грубо говоря это мои реализации методов BinaryReader.ReadString и BinaryReader.WriteString из c# Готовой реализации в java данных штук не нашел. Обновлю коды классов. Кликните здесь для просмотра всего текста
reader
0
|
Модератор
2558 / 1094 / 375
Регистрация: 11.08.2017
Сообщений: 3,332
|
|
10.11.2019, 13:29 [ТС] | 19 |
Файл не приложился((
0
|
10.11.2019, 13:29 | |
10.11.2019, 13:29 | |
Помогаю со студенческими работами здесь
19
Сохранение и открытие бинарного файла используя TFilestream Сохранение в JSON Сохранение в файл JSON Сохранение объекта JSON Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |