Значительной частью того, что поддерживают программисты на С и С++, является специальный код для операций маршалинга и демаршалинга, даже если выбранная форма представления для сохранения и восстановления также проста как дамп бинарной структуры (распространенная методика в не Unix-средах). Современные языки, такие как Python и Java, имеют встроенные функции демаршалинга и маршалинга, которые применимы к любому объекту или потоку байтов, представляющему объект, и в значительной степени сокращают трудозатраты.
Однако эти простые методы часто неудовлетворительны в силу различных причин, включая упомянутые выше проблемы взаимодействия между машинами, а также ту негативную особенность, которая связана с их непрозрачностью для других средств. В ситуации, когда приложение представляет собой сетевой протокол, исходя из соображений экономичности, иногда целесообразно представлять внутреннюю структуру данных (такую, например, как сообщение с адресами отправителя и получателя) не в виде одного большого двоичного объекта данных, а в виде последовательности транзакций или сообщений, которые могут быть отклонены принимающей машиной (так что, например, большое сообщение, может быть отклонено, если адрес получателя указан неверно).
Способность к взаимодействию, прозрачность, расширяемость и экономичность хранения или транзакций — важнейшие темы в проектировании форматов файлов и прикладных протоколов. Способность к взаимодействию и прозрачность требуют, чтобы при проектировании таких конструкций основное внимание было уделено четким формам представления данных, а не удобству реализации или максимальной производительности. Расширяемость также благоприятствует текстовым протоколам, так как двоичные протоколы часто труднее расширять или четко разделять на подмножества. Экономичность транзакций иногда заставляет двигаться в противоположном направлении, однако следует понимать, что выдвижение данного признака на первый план является некоторой формой преждевременной оптимизации. Более дальновидным будет все же противостоять ей.
Наконец, необходимо отметить отличие между форматами файлов данных и конфигурационных файлов, которые часто используются для установки параметров запуска Unix-программ. Самое основное отличие заключается в том, что (за редкими исключениями, такими как конфигурационный интерфейс редактора GNU Emacs) программы обычно не изменяют свои конфигурационные файлы — информационный поток является односторонним (от файла, считываемого при запуске, к настройкам приложения). С другой стороны, форматы файлов данных связывают свойства с именованными ресурсами, и такие файлы считываются и записываются соответствующими приложениями. Конфигурационные файлы, как правило, редактируются вручную и имеют небольшие размеры, тогда как файлы данных генерируются программами и могут достигать произвольных размеров.
Исторически Unix обладает связанными, но различными наборами соглашений для данных двух видов представления. Соглашения для конфигурационных файлов рассматриваются в главе 10; в данной главе описываются только соглашения для файлов данных.
5.1. Важность текстовой формы представления
Каналы и сокеты передают двоичные данные так же, как текст. Однако есть важные причины, для того чтобы примеры, рассматриваемые в главе 7, были текстовыми: причины, связанные с рекомендацией Дуга Макилроя, приведенной в главе 1. Текстовые потоки являются ценным универсальным форматом, поскольку они просты для чтения, записи и редактирования человеком без использования специализированных инструментов. Данные форматы прозрачны (или могут быть спроектированы как таковые).
Кроме того, сами ограничения текстовых потоков способствуют усилению инкапсуляции. Препятствуя сложным формам представления с богатой, плотно закодированной структурой, текстовые потоки также препятствуют созданию программ, которые смешивают внутренние компоненты друг друга. Текстовые потоки также способствуют усилению инкапсуляции. Эта проблема рассматривается в главе 7 при обсуждении технологии RPC.
Если программист испытывает острое желание разработать сложный двоичный формат файла или сложный двоичный прикладной протокол, как правило, мудрым решением будет приостановить работу до тех пор, пока это желание не пройдет. Если основной целью такой разработки является производительность, то внедрение сжатия текстового потока на каком-либо уровне выше или ниже данного протокола прикладного уровня предоставит аккуратную и, вероятно, более производительную конструкцию, чем двоичный протокол (текст хорошо и быстро сжимается).
Читать дальше