Разработка формата обмена (файлами) для java

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

Предпосылки:

  1. должен быть кроссплатформенным
  2. информация, которая должна быть сохранена, включает в себя один POJO и произвольный byte [] s (фактически файлы, POJO хранит свои имена в String [])
  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. Что бы вы посоветовали прочитать по этой теме?

TIA.


person yanchenko    schedule 19.02.2009    source источник
comment
Я бы не стал использовать байт из-за c2.com/cgi/wiki?PowerOfPlainText   -  person keuleJ    schedule 02.02.2011


Ответы (8)


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

  • зачем изобретать новый формат файла?
  • зачем пытаться предотвратить изменение файла только глупыми пользователями?
  • зачем использовать двоичный формат (трудно сжать)?
  • зачем использовать формат, который нельзя проанализировать при получении? (получатель должен получить файл целиком, прежде чем сможет действовать с файлом.)
  • XML уже является сжимаемым форматом сериализации. Итак, вы сериализуете сериализованный формат.
person Pat    schedule 21.02.2009
comment
После некоторой суеты и борьбы я вынужден согласиться. Исчез xml. - person yanchenko; 24.02.2009

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

person TofuBeer    schedule 19.02.2009
comment
Отредактировано для добавления кроссплатформенности. - person yanchenko; 21.02.2009
comment
Когда вы говорите «кросс-платформенный», вы имеете в виду кросс-язык? Сериализация Java является кроссплатформенной, если вы придерживаетесь Java. - person TofuBeer; 22.02.2009

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

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

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

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

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

3) Как правильно рассчитать MD5 в этом случае?

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

4) Что бы вы посоветовали прочитать по этой теме?

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

person Nick Fortescue    schedule 20.02.2009
comment
1) Обоснование: а) должно быть кросс-языковым (отсюда инфляция + xml); на самом деле не имеет значения, читается он человеком или нет, размер имеет значение, хотя б) подпись jar не будет работать, так как я не могу использовать внешний инструмент - person yanchenko; 20.02.2009
comment
c) должен быть дешевым (с точки зрения циклов памяти / процессора) способом удалить byte [] s, оставив xml нетронутым. - person yanchenko; 20.02.2009
comment
Вы можете подписать программно (хотя и не тривиально): onjava. com / pub / a / onjava / 2001/04/12 / signature_jar.html - person Nick Fortescue; 20.02.2009

Посмотрим, это должно быть довольно просто.

Предварительные требования:

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

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

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

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

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

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

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

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

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

Например, этот bean-компонент:

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

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

rO0ABXNyAApTaW1wbGVCZWFuPB4W2ZRCqRICAAFMAAd3ZWJzaXRldAASTGphdmEvbGFuZy9TdHJpbmc7eHB0ABhodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20=

См. этот ответ

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

person OscarRyz    schedule 21.02.2009

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

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

person Barend    schedule 19.02.2009
comment
Да, он также поддерживает zip и tar.gz; кстати, если хотите посмотреть ужастик, посмотрите, как реализован 7z sdk: D - person yanchenko; 21.02.2009

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

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

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

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

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

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

person StaxMan    schedule 24.02.2009

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

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

person Peter Lawrey    schedule 20.02.2009
comment
Конечно 1. Можно легко изменить (отредактировал первый пост по этому требованию) 2. Сжатие чуть хуже 3. Нерациональные личные предпочтения :) - person yanchenko; 21.02.2009

Bencode может оказаться правильным решением.

Вот отличная реализация Дэниела Спивака.

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

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

person yanchenko    schedule 20.02.2009