Файлы конфигурации приложения
Итак, я не хочу начинать священную войну здесь, но мы пытаемся консолидировать способы обработки файлов конфигурации наших приложений и изо всех сил стараемся принять решение о наилучшем подходе, На данный момент каждое распространяемое нами приложение использует свои собственные файлы конфигурации ad-hoc, будь то файлы свойств (стиль ini), XML или JSON (только для внутреннего использования!).
Большая часть нашего кода на данный момент написана на Java, поэтому мы смотрели на Apache Commons Config, но обнаружили, что он довольно многословный. Мы также рассмотрели XMLBeans, но, похоже, вокруг много недоработок. Я также чувствую, что меня подталкивают к XML как к формату, но мои клиенты и коллеги опасаются попробовать что-то еще. Я могу понять это с точки зрения клиента, все слышали об XML, но в конце концов, разве не следует использовать правильный инструмент для работы?
Какие форматы и библиотеки используют люди в производственных системах в наши дни, кто-нибудь еще пытается избежать налога на угловые скобки?
Редактирование: действительно должно быть кроссплатформенным решением: Linux, Windows, Solaris и т. Д., И выбор библиотеки, используемой для взаимодействия с файлами конфигурации, так же важен, как и выбор формата.
15 ответов
XML XML XML XML. Мы говорим здесь о конфигурационных файлах. Не существует "налога на угловые скобки", если вы не сериализуете объекты в условиях высокой производительности.
Файлы конфигурации должны быть удобочитаемыми и понятными для человека, в дополнение к машиночитаемому. XML - хороший компромисс между ними.
Если в вашем магазине есть люди, которые боятся этой новомодной технологии XML, мне вас жаль.
YAML, по той простой причине, что он создает очень удобочитаемые файлы конфигурации по сравнению с XML.
XML:
<user id="babooey" on="cpu1">
<firstname>Bob</firstname>
<lastname>Abooey</lastname>
<department>adv</department>
<cell>555-1212</cell>
<address password="xxxx">ahunter@example1.com</address>
<address password="xxxx">babooey@example2.com</address>
</user>
YAML:
babooey:
computer : cpu1
firstname: Bob
lastname: Abooey
cell: 555-1212
addresses:
- address: babooey@example1.com
password: xxxx
- address: babooey@example2.com
password: xxxx
Примеры были взяты с этой страницы: http://www.kuro5hin.org/story/2004/10/29/14225/062
Первое: это действительно большая дискуссионная проблема, а не быстрый вопрос + а.
Мой любимый сейчас просто включить Lua, потому что
- Я могу разрешить такие вещи, как ширина = высота *(1+1/3)
- Я могу сделать пользовательские функции доступными
- Я могу запретить что-нибудь еще. (невозможно, например, в Python (включая соленья).)
- В любом случае, я, возможно, захочу использовать язык сценариев где-нибудь еще в проекте.
Другой вариант, если данных много - использовать sqlite3, потому что они правы
- Маленький.
- Быстро.
- Надежный.
Выберите любые три.
К которому я хотел бы добавить:
- резервное копирование совсем несложно. (просто скопируйте файл БД.)
- проще переключиться на другую БД, ODBC, что угодно. (чем это из fugly-файла)
Но опять же, это большая проблема. "Большой" ответ на этот вопрос, вероятно, включает в себя некую матрицу функций или список ситуаций, таких как:
Количество данных или короткое время выполнения
- Для больших объемов данных вам может потребоваться эффективное хранилище, например, БД.
- Для коротких запусков (часто) вам может понадобиться что-то, для чего вам не нужно много разбирать, рассмотрите что-то, что может быть напрямую связано с mmap:ed.
К чему относится конфигурация?
- Ведущий:
- Мне нравится YAML в /etc. Это переопределено в окнах?
- Пользователь:
- Вы разрешаете пользователям редактировать конфигурацию в текстовом редакторе?
- Должно ли это быть централизованно управляемым? Реестр / gconf / remote db?
- Может ли пользователь иметь несколько разных профилей?
- Проект:
- Файл (ы) в каталоге проекта? (Контроль версий обычно следует этой модели...)
сложность
- Есть только несколько плоских значений? Рассмотрим YAML.
- Являются ли данные вложенными или как-то зависимыми? (Вот где это становится интересным.)
- Может быть, это желательная возможность разрешить какую-либо форму сценариев?
- Шаблоны можно рассматривать как некие файлы конфигурации.
Без начала новой священной войны настроения, связанные с "налоговой скобкой", - это та область, где я в основном не согласен с Джеффом. В XML нет ничего плохого, он достаточно читабелен для человека (как и файлы YAML, JSON или INI), но помните, что его намерение - читать машины. Большинство комбинаций языка и фреймворка поставляются с каким-то бесплатным анализатором XML, что делает XML довольно хорошим выбором.
Кроме того, если вы используете хорошую IDE, такую как Visual Studio, и если XML поставляется со схемой, вы можете передать схему VS, и волшебным образом вы получите intellisense (например, вы можете получить одну для NHibernate).
Крайне важно подумать о том, как часто вы будете прикасаться к этим файлам после запуска, вероятно, не так часто.
Это все еще говорит обо мне для XML и почему это все еще правильный выбор для файлов конфигурации (от Тима Брея):
"Если вы хотите предоставить данные общего назначения, с которыми получатель может захотеть сделать непредвиденные странные и безумные вещи, или если вы хотите быть действительно параноиком и разборчивым в отношении i18n, или если то, что вы отправляете, больше похоже на документ, чем структура, или если порядок данных имеет значение, или если данные потенциально долгоживущие (например, более, чем секунды), XML- это путь. Мне также кажется, что комбинация XML и XPath поражает приятное место для форматов данных, которые должны быть расширяемыми, то есть довольно легко написать код для обработки XML, который не потерпит неудачу при наличии изменений в формате сообщений, которые не затрагивают интересующую вас часть."
@Guy
Но конфигурация приложения не всегда просто пары ключ / значение. Посмотрите на что-то вроде конфигурации Tomcat, какие порты он прослушивает. Вот пример:
<Connector port="80" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" />
<Connector port="8009"
enableLookups="false" redirectPort="8443" protocol="AJP/1.3" />
Вы можете иметь любое количество разъемов. Определите больше в файле, и существует больше соединителей. Не определяйте больше и больше не существует. Нет хорошего способа (imho) сделать это с простыми старыми парами ключ / значение.
Если конфигурация вашего приложения проста, то что-то простое, например, INI-файл, который читается в словарь, вероятно, подойдет. Но для чего-то более сложного, такого как конфигурация сервера, INI-файл будет очень трудно поддерживать, и что-то более структурное, такое как XML или YAML, будет лучше. Все зависит от поставленной задачи.
XML, JSON, INI.
Все они имеют свои сильные и слабые стороны.
В контексте приложения я чувствую, что уровень абстракции - это важная вещь.
Если вы можете выбрать способ структурирования данных, который является хорошим промежуточным звеном между удобочитаемостью для человека и тем, как вы хотите получить доступ к данным в коде / абстрагировать их, то вы великолепны.
В основном я использую XML там, где я работаю, и я не могу поверить, что файл конфигурации, загруженный в кеш как объекты при первом чтении или после его записи, а затем абстрагирования от остальной части программы, на самом деле является большой частью удар ни по процессору, ни по дисковому пространству.
И это тоже довольно читабельно, если вы правильно структурируете файл.
И все языки на всех платформах поддерживают XML через некоторые довольно распространенные библиотеки.
Мы используем конфигурационные файлы в стиле ini. Мы используем библиотеку Nini для управления ими. Нини делает его очень простым в использовании. Nini изначально был для.NET, но был перенесен на другие платформы с использованием Mono.
@Herms
Я действительно имел в виду придерживаться рекомендованного способа, которым программное обеспечение должно хранить значения конфигурации для любой конкретной платформы.
То, что вы часто получаете, это также рекомендуемые способы, которыми они должны / могут быть изменены. Например, меню конфигурации в программе или панель конфигурации в приложении "system prefs" (например, для системных служб). Не позволяя конечным пользователям изменять их напрямую через RegEdit или NotePad...
Зачем?
- Конечные пользователи (= клиенты) привыкли к своим платформам
- Система для резервного копирования может лучше сохранять "безопасные настройки" и т. Д.
@ninesided
Что касается " выбора библиотеки ", попробуйте связать (статическую ссылку) любую выбранную библиотеку, чтобы снизить риск вступления в войну версий и конфликтов на компьютерах конечных пользователей.
Может быть, немного касательно здесь, но я считаю, что файл конфигурации должен быть прочитан в словарь / хэш-таблицу значений ключей при первом запуске приложения и с этого момента всегда получать доступ через этот объект для скорости. Обычно таблица ключ / значение начинается как строка за строкой, но вспомогательные функции в объекте делают такие вещи, как DateTime GetConfigDate(строковый ключ) и т. Д.
Если ваш файл конфигурации предназначен для однократной записи, только для чтения при загрузке, а ваши данные представляют собой набор пар имя-значение, то ваш лучший выбор - тот, который ваш разработчик может начать работать первым.
Если ваши данные немного сложнее, с вложенностью и т. Д., Вам, вероятно, лучше использовать YAML, XML или SQLite.
Если вам нужны вложенные данные и / или возможность запрашивать данные конфигурации после загрузки, используйте XML или SQLite. Оба имеют довольно хорошие языки запросов (XPATH и SQL) для структурированных / вложенных данных.
Если ваши данные конфигурации сильно нормализованы (например, 5-ая нормальная форма), вам лучше использовать SQLite, потому что SQL лучше подходит для работы с сильно нормализованными данными.
Если вы планируете записывать данные конфигурации во время работы программы, то лучше использовать SQLite. Например, если вы загружаете данные конфигурации с другого компьютера, или если вы основываете будущие решения о выполнении программы на данных, собранных в ходе предыдущего выполнения программы. SQLite реализует очень надежный механизм хранения данных, который чрезвычайно трудно повредить, если у вас есть перебои с питанием или программы, которые зависают в несовместимом состоянии из-за ошибок. Коррумпированные данные приводят к высокой стоимости поддержки на местах, и SQLite будет работать намного лучше, чем любое домашнее решение или даже популярные библиотеки вокруг XML или YAML.
Проверьте мою страницу для получения дополнительной информации о SQLite.
Насколько я знаю, реестр Windows больше не является предпочтительным способом хранения конфигурации, если вы используете.NET - большинство приложений теперь используют System.Configuration [1, 2]. Поскольку это также основано на XML, кажется, что все движется в направлении использования XML для конфигурации.
Если вы хотите остаться кроссплатформенным, я бы сказал, что использование какого-либо текстового файла было бы лучшим путем. Что касается форматирования указанного файла, вы можете принять во внимание, будет ли человек манипулировать им или нет. XML кажется немного более дружественным к ручным манипуляциям, чем файлы INI из-за видимой структуры файла.
Что касается налога на угловые скобки - я не беспокоюсь об этом слишком часто, так как библиотеки XML заботятся о его абстрагировании. Единственный раз, когда это может быть рассмотрено, если у вас очень мало места для хранения, и каждый байт имеет значение.
[1] Пространство имен System.Configuration - http://msdn.microsoft.com/en-us/library/system.configuration.aspx
[2] Использование файлов конфигурации приложения в.NET - http://www.developer.com/net/net/article.php/3396111
Мы используем файлы свойств просто потому, что Java поддерживает их изначально. Пару месяцев назад я увидел, что SpringSource Application Platform использует JSON для настройки своего сервера, и это выглядит очень интересно. Я сравнил различные нотации конфигурации и пришел к выводу, что XML кажется наиболее подходящим на данный момент. Он имеет хорошую поддержку инструментов и является довольно независимым от платформы.
Я думаю, что единственная важная вещь - это выбрать формат, который вы предпочитаете и можете быстро перемещаться. XML и JSON являются прекрасными форматами для конфигов и широко поддерживаются - техническая реализация не в этом суть проблемы, метинкс. Это 100% о том, что делает задачу настройки файлов конфигурации проще для вас.
Я начал использовать JSON, потому что я довольно много работаю с ним как с форматом передачи данных, а сериализаторы облегчают загрузку в любую среду разработки. Я считаю, что JSON легче читать, чем XML, что делает обработку нескольких сервисов, каждый из которых использует конфигурационный файл, который изменяется довольно часто, намного проще для меня!
Re: комментарий эпателя
Я думаю, что первоначальный вопрос заключался в том, чтобы задавать конфигурацию приложения, а не просто сохранять пользовательские настройки. Предложения, которые вы дали, выглядят скорее для пользовательских настроек, чем для конфигурации приложения, и обычно это не то, с чем пользователь когда-либо имеет дело напрямую (приложение должно предоставить параметры конфигурации в пользовательском интерфейсе, а затем обновить файлы). Я действительно надеюсь, что вы никогда не заставите пользователя просматривать / редактировать реестр.:)
Что касается настоящего вопроса, я бы сказал, что XML, вероятно, в порядке, так как многие люди привыкли использовать его для конфигурации. Пока вы упорядочиваете значения конфигурации простым в использовании способом, "налог на угловые скобки" не должен быть слишком плохим.
На какой платформе вы работаете? Я бы рекомендовал использовать для этого предпочтительный / общий метод.
- MacOSX - списки
- Win32 - Реестр (или есть новый здесь, давно я его разработал)
- Linux / Unix - ~ /.apprc (возможно, имя-значение)