Лучшие форматы входных файлов для C++?

Я начинаю работу над новым программным обеспечением, которое в конечном итоге потребует надежного и расширяемого файлового ввода-вывода. Там очень много форматов. XML, JSON, INI и т. д. Тем не менее, всегда есть плюсы и минусы, поэтому я подумал, что могу попросить сообщество внести свой вклад.

Вот несколько приблизительных требований:

  1. Формат "стандартный"... Я не хочу изобретать велосипед, если в этом нет необходимости. Это не обязательно должен быть формальный стандарт IEEE, но что-то, о чем вы могли бы погуглить и получить некоторую информацию как новый пользователь, может иметь некоторые инструменты поддержки (редакторы) помимо vi. (Хотя пользователи программного обеспечения, как правило, хорошо разбираются в компьютерах и с удовольствием используют vi.)
  2. Легко интегрируется с C++. Я не хочу тянуть с собой 100-мегабайтную библиотеку и три разных компилятора, чтобы запустить ее.
  3. Поддерживает табличный ввод (2d, n-мерный)
  4. Поддерживает типы POD
  5. Может расширяться, если требуется больше входных данных, хорошо привязывается к переменным и т. д.
  6. Скорость парсинга не так уж важна
  7. В идеале писать (размышлять) так же легко, как и читать
  8. Хорошо работает на Windows и Linux
  9. Поддерживает композитинг (один файл ссылается на другой файл для чтения и т. д.)
  10. Человек читаемый

В идеальном мире я бы использовал библиотеку только для заголовков или какую-нибудь чистую реализацию STL, но я не против использовать Boost или какую-нибудь небольшую внешнюю библиотеку, если она работает хорошо.

Итак, что вы думаете о различных форматах? Недостатки? Преимущества?

Изменить

Варианты рассмотреть? Что еще добавить?

  • XML
  • YAML
  • SQLite
  • Буферы протокола Google
  • Повышение сериализации
  • INI
  • JSON

person DigitalInBlue    schedule 05.02.2013    source источник
comment
Какие типы данных вы хотите представить? Только на английском или есть проблема? Насколько важно иметь компактное представление? Необходимо взаимодействие с другими языками?   -  person vonbrand    schedule 05.02.2013
comment
Для текстового формата: XML - с соответствующими библиотеками. INI не работает с иерархическими/размерными данными, а JSON, хотя и чертовски приятно использовать из JavaScript, не имеет некоторых приятных функций и инструментов XML.   -  person    schedule 05.02.2013
comment
C++ напрямую не поддерживает структурированные файлы. Вам всегда нужен фрагмент кода для разбора или создания чего-то более сложного, чем чистый двоичный или текстовый файл. XML/JSON — прекрасный выбор, и вы можете расширить их, придав вещам особое значение. Однако вы должны понимать, что когда у вас много данных, любой формат становится плохо читаемым в обычном текстовом редакторе.   -  person Alexey Frunze    schedule 05.02.2013
comment
@vonbrand - Да. Только английский. Данные будут конфигурационными, но в основном числовыми по своей природе. Наиболее сложными данными будут таблицы порядка 1024x1024x1024 элементов.   -  person DigitalInBlue    schedule 05.02.2013
comment
Возможно, достаточно какого-то варианта INI? Зависит от того, насколько сложна структура данных...   -  person vonbrand    schedule 05.02.2013
comment
Чем больше я исследую это, тем больше я вижу требование массива как длинный шест в палатке. Деревья свойств JSON и Boost не обеспечивают здесь хорошей поддержки массивов произвольного размера.   -  person DigitalInBlue    schedule 05.02.2013
comment
Попробуйте хлопья: uscilab.github.io/cereal отлично работает.   -  person Erik Aronesty    schedule 11.03.2015


Ответы (4)


Есть один отличный формат, отвечающий всем вашим критериям:

SQLite!

Прочтите статью об использовании SQLite в качестве формата файла приложения. Также, пожалуйста, посмотрите Google Tech Talk Д. Ричарда Хиппа (автора SQLite) об этом очень тема.

Теперь давайте посмотрим, насколько SQLite соответствует вашим требованиям:

Формат является "стандартным"

SQLite стал предпочтительным форматом для большинства мобильных сред и для многих настольных приложений (Firefox, Thunderbird, Google Chrome, Adobe Reader и т. д.).

Легко интегрируется с C++

SQLite имеет стандартный интерфейс C, который представляет собой только один исходный файл и один заголовочный файл. Существуют также оболочки C++.

Поддерживает табличный ввод (2D, n-мерный)

Таблица SQLite настолько таблична, насколько вы можете себе представить. Чтобы представить, скажем, трехмерные данные, создайте таблицу со столбцами x,y,z,value и сохраните свои данные в виде набора строк следующим образом:

x1,y1,z1,value1
x2,y2,z2,value2
...

Поддерживает типы POD

Я предполагаю, что под POD вы имели в виду обычные старые данные или BLOB. SQLite позволяет хранить поля BLOB как есть.

Может расширяться по мере необходимости дополнительных входных данных, хорошо привязывается к переменным

Вот где он действительно светит.

Скорость парсинга не очень важна

Но скорость SQLite превосходна. На самом деле синтаксический анализ в основном прозрачен.

В идеале писать (размышлять) так же легко, как и читать

Просто используйте INSERT для записи и SELECT для чтения — что может быть проще?

Хорошо работает в Windows и Linux

Вы держите пари, и все другие платформы, а также.

Поддерживает композитинг (один файл ссылается на другой файл для чтения)

Вы можете ПРИСОЕДИНЯТЬ одну базу данных к другой.

Удобочитаемый

Не в двоичном виде, но есть много отличных браузеров/редакторов SQLite. Мне нравится SQLite Expert Personal для Windows и sqliteman в Linux. Существует также плагин редактора SQLite для Firefox.


Есть и другие преимущества, которые SQLite дает вам бесплатно:

  • Данные индексируются, что упрощает поиск. Вы просто не можете сделать это, используя XML, JSON или любые другие текстовые форматы.

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

  • SQLite полностью транзакционный: он гарантирует постоянную согласованность ваших данных. Даже если ваше приложение (или весь компьютер) выйдет из строя, ваши данные будут автоматически восстановлены до последнего известного согласованного состояния при следующей первой попытке подключения к базе данных.

  • SQLite сохраняет ваши данные дословно: вам не нужно беспокоиться об экранировании ненужных символов в ваших данных (включая нулевые байты, встроенные в ваши строки) — просто всегда используйте подготовленные операторы — это все, что нужно, чтобы сделать его прозрачным. Это может быть большой и раздражающей проблемой при работе с форматами текстовых данных, в частности с XML.

  • SQLite хранит все строки в Unicode: UTF-8 (по умолчанию) или UTF-16. Другими словами, вам не нужно беспокоиться о кодировке текста или международной поддержке вашего формата данных.

  • SQLite позволяет обрабатывать данные небольшими порциями (фактически построчно), поэтому он хорошо работает в условиях нехватки памяти. Это может быть проблемой для любых текстовых форматов, потому что часто им нужно загрузить весь текст в память, чтобы проанализировать его. Конечно, существует несколько эффективных потоковых синтаксических анализаторов XML, но в целом любой синтаксический анализатор XML будет довольно жадным по памяти по сравнению с SQLite.

person mvp    schedule 05.02.2013
comment
Спасибо. Это отличный вклад. Я проверю это больше! - person DigitalInBlue; 05.02.2013
comment
Не похоже, что SQLite поддерживает массивы произвольного размера. - person DigitalInBlue; 05.02.2013
comment
Таблица SQLite является массивом произвольного размера, не так ли? - person mvp; 05.02.2013
comment
Могу ли я порекомендовать code Synthetic.com/products/odb как хорошую оболочку SQLite? - person ArtemGr; 06.02.2013

Поработав немного как с XML, так и с json, вот мое довольно субъективное мнение об обоих как о расширяемых форматах сериализации:

  • Формат является «стандартным»: да для обоих
  • Легко интегрируется с C++: Да для обоих. В каждом случае вы, вероятно, столкнетесь с какой-то библиотекой, чтобы справиться с этим. В Linux libxml2 является стандартом, а libxml++ является для него оболочкой C++; вы должны иметь возможность получить оба из менеджера пакетов вашего дистрибутива. Потребуются небольшие усилия, чтобы заставить тех, кто работает в Windows. Кажется, в Boost есть некоторая поддержка json, но я ее не использовал; Я всегда имел дело с json с помощью библиотек. На самом деле, путь к библиотеке ни для кого не слишком обременительный.
  • Поддерживает табличный ввод (2d, n-мерный): да для обоих
  • Поддерживает типы POD: Да для обоих
  • Может расширяться по мере необходимости: Да для обоих — это одно большое преимущество для них обоих.
  • Хорошо привязывается к переменным: если вы имеете в виду, что внутри самого файла есть способ сказать: «Этот фрагмент данных должен быть автоматически десериализован в эту переменную в моей программе», тогда нет для обоих.
  • Писать (размышлять) так же легко, как и читать: зависит от используемой вами библиотеки, но, по моему опыту, да для обеих. (На самом деле вы можете сносно писать json с помощью printf().)
  • Хорошо работает в Windows и Linux: Да, в обоих случаях, а также в Mac OS X.
  • Поддерживает один файл, ссылающийся на другой файл для чтения: если вы имеете в виду что-то похожее на C #include, то у XML есть некоторые возможности для этого (например, объекты документа), а у json нет.
  • Читаемый человеком: оба обычно написаны в UTF-8 и допускают разрывы строк и отступы, поэтому могут быть удобочитаемыми. Тем не менее, я только что работал с XML-файлом размером 479 КБ, который состоит из одной строки, поэтому мне пришлось запустить его через симпатичный принтер, чтобы понять его смысл. json также может быть довольно нечитаемым, но, по моему опыту, он часто форматируется лучше, чем XML.

При запуске новых проектов я обычно предпочитаю json; он более компактный и более удобочитаемый. Основная причина, по которой я мог бы выбрать XML, а не json, заключалась в том, что я беспокоился о получении плохо сформированных документов, поскольку XML поддерживает автоматическую проверку формата документа, в то время как вам нужно написать свой собственный код проверки с помощью json.

person Bob Murphy    schedule 05.02.2013
comment
Это хорошая информация. Раньше я в основном использовал XML, но табличный ввод показался мне неудобным. Поддерживает один файл, ссылающийся на другой файл для чтения: если вы имеете в виду что-то похожее на C #include, то у XML есть некоторые возможности для этого (например, объекты документа), а у json нет. Это приятно знать, удивительно и, вероятно, исключает JSON. - person DigitalInBlue; 05.02.2013
comment
Некоторые преимущества, которые я нахожу в использовании XML по сравнению с JSON: схемы/валидаторы/информационные наборы, XPath/XQuery, поддержка базы данных (например, SQL Server), пространства имен, атрибуты и дочерние элементы. И нет, нет, я не собираюсь говорить о XSLT 1.0 - это может уйти навсегда :D JSON хорош для REST, веб-сервисов, интеграции с JavaScript и небольших документов. Однако за эту простоту приходится платить стандартизированными расширенными функциями и инструментами — не все продукты Enterprise должны быть сложными в использовании, даже если многие продукты, основанные на XML, таковы. - person ; 05.02.2013
comment
@pst: внесено исправление в отношении удобочитаемости json. - person Bob Murphy; 05.02.2013

Ознакомьтесь с буферами Google. Это соответствует большинству ваших требований.

Из их документации шаги высокого уровня:

Определите форматы сообщений в файле .proto.
Используйте компилятор буфера протокола.
Используйте API буфера протокола C++ для записи и чтения сообщений.

person David D    schedule 05.02.2013
comment
У вас есть опыт работы с протобуферами Google? Я чувствовал, что было сложно расширять сообщения и поддерживать обратную совместимость, но я не реализовал с ними никаких решений, чтобы знать, насколько легко их поддерживать для большого проекта с потенциально большими входными данными (от десятков до сотен файлов, составляющих один ввод). задавать). - person DigitalInBlue; 05.02.2013
comment
Похоже, протобуферы не поддерживают n-мерные массивы. ссылка - person DigitalInBlue; 05.02.2013
comment
@DigitalInBlue У меня есть некоторый опыт работы с буферами Google. Я использовал их в научно-исследовательском проекте для удаленного управления аппаратным обеспечением. Обновление типа сообщения, поиск раздела с таким же названием довольно прост. , но требует некоторого, я бы посоветовал не использовать обязательное ключевое слово так часто, как вам это может сойти с рук. Что касается N-мерных массивов, предоставленная вами ссылка описывает довольно хороший способ их эмуляции. Почему бы вам не сделать это, как они предложили? - person David D; 05.02.2013
comment
Спасибо за информацию. Нет причин, по которым я бы не поступил так, как было предложено, просто пытаясь понять все тонкости различных стандартов, прежде чем будет принято решение. Эмуляция в протобуферах не идеальна, но, возможно, не мешает. - person DigitalInBlue; 05.02.2013

Для моих целей я думаю, что лучше всего использовать XML.

  1. Формат является стандартным, но допускает модификацию и гибкость схемы для изменения по мере развития требований программы.
  2. Есть несколько вариантов библиотеки. Некоторые из них больше (Xerces-C), некоторые меньше (ezxml), но есть много вариантов, поэтому мы не будем привязаны к одному поставщику или очень конкретному решению.
  3. Он может поддерживать табличный ввод (2d, n-мерный). Это требует дополнительной работы по синтаксическому анализу на «нашей» стороне и, вероятно, является самым слабым местом для XML.
  4. Поддерживает типы POD: Абсолютно.
  5. Может расширяться по мере того, как требуется больше входных данных, хорошо привязывается к переменным и т. д. за счет модификации схемы и модификации синтаксического анализатора.
  6. Скорость синтаксического анализа не очень важна, поэтому обработка текстового файла или файлов не является проблемой.
  7. XML можно программно написать так же легко, как и прочитать.
  8. Хорошо работает в Windows и Linux или любой другой ОС, поддерживающей C и текстовые файлы.
  9. Поддерживает композитинг (один файл ссылается на другой файл для чтения и т. д.)
  10. Человекочитаемый со многими текстовыми редакторами (Sublime, vi и т. д.), поддерживающими подсветку синтаксиса из коробки. Многие веб-браузеры хорошо отображают данные.

Спасибо за отличные отзывы! Я думаю, что если бы мы хотели чисто бинарное решение, скорее всего, мы бы пошли по пути Protocol Buffers или boost::serialization.

person DigitalInBlue    schedule 08.02.2013
comment
Хотя я не отрицал это, я прокомментирую: В SO, поскольку ваш ответ не предлагает решения, не охватываемого другими ответами, писать то, что вы сделали, как ответ и принимать это, - это плохой тон. Лучше принять лучший ответ кого-то другого (вы все еще можете изменить это, я думаю), если только ни один из них не является хорошим... Кроме того, если ваш ответ на самом деле не добавляет что-то полезное (это не так), лучше написать выбранное вами решение как комментарий. - person hyde; 10.02.2013
comment
Я понизил это. Написать свой собственный ответ, эффективно списывая ответы других людей, а затем принять его как ответ, это действительно дурной тон, и здесь это работает против системы поощрения. - person Bill Weinman; 09.11.2013