Разработка (файлового) формата обмена для Java - PullRequest
0 голосов
/ 20 февраля 2009

Я хочу предложить двоичный формат для передачи данных между экземплярами приложения в форме POF (Plain Old Files;)).

Требования:

  1. должно быть кроссплатформенным
  2. информация, подлежащая сохранению, включает один POJO и произвольные байты [] (на самом деле файлы, POJO хранит свои имена в строке [])
  3. требуется только последовательный доступ
  4. должен быть способом проверки согласованности данных
  5. должен быть маленьким и быстрым
  6. должен помешать обычному пользователю с архиватором + блокнотом изменять данные

В настоящее время я использую DeflaterOutputStream + OutputStreamWriter вместе с InflaterInputStream + InputStreamReader для сохранения / восстановления объектов, сериализованных с XStream, по одному объекту на файл. Читатели / Авторы используют UTF8. Теперь необходимо расширить это для поддержки ранее описанного. Моя идея формата:

{serialized to XML object}
{delimiter}
{String file name}{delimiter}{byte[] file data}
{delimiter}
{another String file name}{delimiter}{another byte[] file data}
...
{delimiter}
{delimiter}
{MD5 hash for the entire file}
  1. Это выглядит вменяемым?
  2. Что бы вы использовали для разделителя и как бы вы его определили?
  3. Правильный способ расчета MD5 в этом случае?
  4. Что бы вы предложили прочитать по этому вопросу?

ТИА.

Ответы [ 8 ]

3 голосов
/ 21 февраля 2009

выглядит безумно.

  • зачем изобретать новый формат файла?
  • зачем пытаться запретить изменение файла только глупым пользователям?
  • зачем использовать двоичный формат (трудно сжать)?
  • зачем использовать формат, который не может быть проанализирован во время получения? (Получатель должен получить файл целиком, прежде чем он сможет воздействовать на файл.)
  • XML уже является форматом сериализации, который можно сжимать. Итак, вы сериализуете сериализованный формат.
2 голосов
/ 21 февраля 2009

Давайте посмотрим, это должно быть довольно просто.

Требования:

0. должен быть кроссплатформенным

1. сохраняемая информация включает в себя один POJO и произвольные байты [] (на самом деле файлы, POJO хранит свои имена в строке [])

2. требуется только последовательный доступ

3. должен быть способ проверки согласованности данных

4. должен быть маленьким и быстрым

5. должен помешать обычному пользователю с архиватором + блокнотом изменять данные

Что ж, угадайте, что у вас это уже есть, встроенная платформа уже есть: Сериализация объектов

Если вам нужно уменьшить объем данных, отправляемых по проводам, и обеспечить настраиваемую сериализацию (например, вы можете отправить только 1,2,3 для данного объекта без использования имени атрибута или ничего подобного, и прочитать их в та же последовательность,) вы можете использовать это как-то «Скрытая функция»

Если вам действительно это нужно в текстовом формате, вы также можете его кодировать, оно занимает почти такое же количество байтов.

Например, этот боб:

import java.io.*;
public class SimpleBean implements Serializable  { 
    private String website = "http://stackoverflow.com";
    public String toString() { 
        return website;
    }
}

Можно представить так:

rO0ABXNyAApTaW1wbGVCZWFuPB4W2ZRCqRICAAFMAAd3ZWJzaXRldAASTGphdmEvbGFuZy9TdHJpbmc7eHB0ABhodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20=

См. Этот ответ

Кроме того, если вам нужен озвученный протокол, вы также можете выбрать Protobuf , формат внутреннего обмена Google.

2 голосов
/ 20 февраля 2009

1) Это выглядит вменяемым?

Это выглядит довольно вменяемым. Однако, если вы собираетесь изобретать свой собственный формат, а не просто использовать сериализация Java , у вас должна быть веская причина. У вас есть веские причины (в некоторых случаях они существуют)? Одна из стандартных причин использования XStream состоит в том, чтобы сделать результат понятным для человека, который двоичный формат немедленно теряет. У вас есть веская причина для двоичного формата, а не для человека удобочитаемым? См. этот вопрос о том, почему читаемое человеком хорошо (и плохо).

Не было бы проще просто положить все в подписанную банку. Уже есть стандартные библиотеки Java и инструменты для этого, и вы получаете сжатие и проверку.

2) Что бы вы использовали для разделителя и как его определить?

Вместо разделителя я бы явно сохранял длину каждого блока перед блоком. Это так же просто, и предотвращает необходимость избегать разделителя, если он появляется сам по себе.

3) Правильный способ расчета MD5 в этом случае?

Здесь приведен пример кода , который выглядит разумным.

4) Что бы вы предложили почитать по теме?

На предмет сериализации? Я читал о сериализации Java, JSON и сериализации XStream, чтобы понять все плюсы и минусы каждого, особенно преимущества файлов, удобочитаемых человеком. Я также хотел бы взглянуть на классический формат файла, например, от Microsoft, чтобы понять возможные решения по проектированию в те времена, когда каждый байт имел значение, и как они были расширены. Например: Формат файла WAV .

2 голосов
/ 20 февраля 2009

Разве сериализация модели (если вы в MVC) не будет другим способом? Я предпочел бы использовать вещи на языке (или в стандартных библиотеках), а не накатывать свои, если это возможно. Единственная проблема, с которой я могу столкнуться, это то, что размер файла может быть больше, чем вы хотите.

1 голос
/ 24 февраля 2009

Я согласен с тем, что на самом деле не похоже, что вам нужен новый или двоичный формат. Если вы действительно хотите двоичный формат, почему бы сначала не рассмотреть один из них:

  • Двоичный XML (быстрый набор, Bnux)
  • Hessian
  • буферы пакетов Google

Но кроме того, многие текстовые форматы должны работать просто отлично (или, возможно, лучше); более простой в отладке, расширенная поддержка инструментов, сжимает примерно до того же размера, что и бинарный (бинарное сжатие плохо, и теория информации предполагает, что для той же эффективной информации достигается та же степень сжатия - и это было верно в моем тестировании).

Так что, возможно, также рассмотрим:

  • Джсон работает хорошо; двоичная поддержка через base64 (скажем, с http://jackson.codehaus.org/)
  • XML тоже неплох; эффективные потоковые парсеры, некоторые с поддержкой base64 (http://woodstox.codehaus.org/, «API типизированного доступа» в разделе «org.codehaus.stax2.typed.TypedXMLStreamReader ').

Так что это звучит так, будто вы просто хотите создать что-то свое. Ничего плохого в этом нет, как хобби, но если это так, вы должны рассматривать это как таковое. Вероятно, это не является обязательным требованием для системы, которую вы строите.

1 голос
/ 20 февраля 2009

Вы можете использовать библиотеку zip (rar / 7z / tar.gz / ...). Многие из них существуют, большинство из них хорошо протестированы, и это, вероятно, сэкономит вам время.

Возможно, не так весело, хотя.

0 голосов
/ 21 февраля 2009

Возможно, вы могли бы объяснить, как это лучше, чем использовать существующий формат файла, такой как JAR.

Большинство стандартных форматов файлов этого типа просто используют CRC для ускорения расчета. MD5 более подходит, если вы хотите предотвратить преднамеренное изменение.

0 голосов
/ 20 февраля 2009

Bencode может быть путь.

Вот отличная реализация от Daniel Spiewak.

К сожалению, спецификация bencode не поддерживает utf8, что является для меня показателем.

Возможно, мы подойдем к этому позже, но в настоящее время xml кажется лучшим выбором (с BLOB-объектами, сериализованными как карта).

...