Могу ли я разделить поток вывода объекта на несколько файлов

#java #serialization #deserialization

Вопрос:

Я хочу записать данные из моей игры в файл, чтобы я мог воссоздать состояние после перезапуска моей программы. настоящее время я не использую сериализацию javas по умолчанию (де -), так как она сама по себе устраняет циклические ссылки и дубликаты объектов и поэтому очень проста в использовании. Теперь при сериализации все данные записываются в один файл, что кажется довольно непрактичным, если файл поврежден. Это фактически означало бы, что все данные будут потеряны. Я бы предпочел, чтобы данные были записаны в несколько небольших тематических файлов, таких как данные об игроках, данные о мире, данные о врагах и т. Д… . Может ли это быть достигнуто, в необходимость снова и снова создавать новые потоки вывода объектов, потому что я хочу использовать внутреннее обнаружение дубликатов объектов? Перед переключением на сериализацию Java по умолчанию я использовал fasterxml и формат json, который, к сожалению, не обеспечивал такой удобной обработки дубликатов и циклических ссылок, как Java. С другой стороны, хранение данных в нескольких файлах меньшего размера не было проблемой.

Комментарии:

1. Почему бы вероятности повреждения не увеличиться пропорционально количеству задействованных файлов? Коррупцию было бы проще исправить, кстати, с помощью удобочитаемой XMLSerializer

2. Пожалуйста, предоставьте достаточно кода, чтобы другие могли лучше понять или воспроизвести проблему.

Ответ №1:

поскольку он сам по себе заботится о циклических ссылках и дубликатах объектов и поэтому очень прост в использовании.

Ты сам это сказал.

У вас есть два варианта:

[1] Вы используете механизм сериализации java по умолчанию, который «прост в использовании», но это то, что есть. Вы не можете изменить, как это работает, вы не получаете файлы, вы можете ознакомиться с ничего, кроме Java сериализации механизм, и это довольно сложно, чтобы обновить игру и по-прежнему иметь возможность читать старые резервные файлы (вы можете, но сделать это в течение нескольких модификациях и общая сумма кода в кодовой базе, посвященный чтению сохранять файлы будут дольше и гораздо сложнее, чем если бы вы просто спасли с помощью Джексона например, в XML или JSON или protobuf даже и выкатил свой код в первую очередь).

[2] Вы пишете свою собственную систему.

Ты не можешь взять свой торт и съесть его тоже, о чем ты просишь.

Обратите внимание, что попытка защитить от повреждения диска-достаточно хорошая цель, но «сохранить в файлы меньшего размера» — это все равно, что добавить третий замок на дверь, пока окна широко открыты. Теоретически это помогает, но вы фокусируетесь на совершенно неправильной вещи.

Например, если один файл поврежден, остальные в порядке — и что с того? Вы все еще не можете загрузить игру. Если ваше намерение таково: Ах, но теперь я могу зайти и исправить этот файл — отлично. Проблема не в «нескольких файлах», проблема в том, что вам нужен формат файла сохранения, который вы можете разумно редактировать. встроенный механизм сериализации java полностью не соответствует этому требованию и не может быть исправлен в этом отношении.

Хорошие идеи:

  • Добавьте контрольные суммы.
  • Запишите формат файла сохранения, который отключен от ваших представлений в памяти. Вы сами сказали: в вашем представлении памяти повсюду есть циклические ссылки и повторяющиеся объекты. Это, вероятно, все хорошие идеи при запуске игры, но в играх с сохранением это действительно плохо, если вы хотите, чтобы ваши файлы сохранения имели шансы на то, что снежный ком переживет некоторое повреждение.
  • Сделайте несколько сохранений.
  • Прежде всего: Убедитесь, что файл сохранения игры настолько мал, насколько это возможно: файлы меньшего размера записываются быстрее (это означает, что вы можете создавать их больше).
  • Убедитесь, что они легко возвращаются. На самом деле вам не нужно несколько файлов. Застегни их, если нужно. Отдельные небольшие файлы-лучший способ: Вы можете автоматически сохранять в мгновение ока (файлы меньшего размера также пишутся быстрее!) и даже сохранять их в облаке или на резервных дисках или еще где-нибудь. Если это несколько кб, и у пользователя есть папка dropbox, gdrive, onedrive и т. Д., Вы можете просто спамить сохраненные игры там. Это не так разумно, если размер сохраненной игры составляет 50 МБ. Вы должны заархивировать этот файл, даже если это только один файл (вы можете использовать GZipOutputStream и со для этого). Обратите внимание, что если вы используете строковые ключи (JSON или XML), сжатие сэкономит вам массу места. Если вы используете двоичный формат (например, protobuf), это будет иметь меньшее значение.. но я бы все равно застегнул молнию.
  • Напишите инструмент, который проходит через сохранение игры и, по крайней мере, пытается исправить любые ошибки. Механизм сериализации Java представляет собой непрозрачный двоичный формат, что означает, что он не справляется с этой задачей: вы не можете прочитать это и устранить проблемы.

Комментарии:

1. Это очень исчерпывающий ответ. Я, вероятно, попытаюсь написать свою собственную систему, снова используя fasterxml и сохраняя объекты в хэш-карте, чтобы предотвратить дублирование объектов при загрузке. Это займет некоторое время и усилия, но я действительно хочу справиться с этим правильно. Архивирование файлов-это нечто такое простое и в то же время такое эффективное, но я даже не думал об этом. Большое спасибо