В фреймворках программирования macOS , iOS , NeXTSTEP и GNUstep файлы списков свойств — это файлы, в которых хранятся сериализованные объекты . Файлы списков свойств используют расширение имени файла и поэтому часто называются файлами p-list . .plist
Файлы списков свойств часто используются для хранения настроек пользователя. Они также используются для хранения информации о пакетах и приложениях , задача, которую выполнял ресурсный форк в старой Mac OS.
Списки свойств также используются для строк локализации для разработки. Эти файлы используют расширения .strings
или .stringsdict
. Первый — это «сокращенный» старый plist, содержащий только один словарь без фигурных скобок (см. propertyListFromStringsFileFormat ), [1] тогда как последний — полноценный plist. Xcode также использует расширение для старых plist, используемых в качестве файлов проекта. .pbxproj
Поскольку данные, представленные списками свойств, несколько абстрактны , базовый формат файла может быть реализован многими способами. А именно, NeXTSTEP использовал один формат для представления списка свойств, а последующие фреймворки GNUstep и macOS представили различные форматы.
В NeXTSTEP списки свойств были разработаны так, чтобы их мог читать человек и редактировать вручную, сериализовались в ASCII в синтаксисе, похожем на язык программирования . Этот же формат использовался в OPENSTEP .
"This is a plist string\n"
; допускаются более простые строки без кавычек, если они состоят из буквенно-цифровых символов и одного из символов _$+/:.- .< [hexadecimal codes in ASCII] >
( "1", "2", "3" )
. Допускаются запятые в конце.{ "key" = "value"; ... }
. Левая часть должна быть строкой, но она может быть без кавычек./* This is a comment */
и // This is a line comment
.Одним из ограничений исходного формата списка свойств NeXT является то, что он не может представлять объект NSValue (число, логическое значение и т. д.). В результате эти значения должны быть преобразованы в строку и «нечетко» восстановлены приложением. [2] Другим ограничением является то, что не определена официальная 8-битная кодировка. [3]
Утилита defaults , представленная в OPENSTEP (1996), может использоваться для управления файлами plist, используемыми для хранения предпочтений (известных как defaults в NeXTSTEP, отсюда и название) в командной строке через их домен предпочтений, и эта утилита может использоваться для редактирования произвольных файлов plist. Эта утилита заменила три старые команды (dread, dwrite и dremove). [4]
GNUstep принимает формат NeXTSTEP с дополнениями для представления типов данных NSValue и NSDate. Новые типизированные записи имеют форму <* T ...> , где T — однобуквенный код типа. Например, NSValue логического значения YES представляется как <*BY> , а объекты NSDate представляются как . [5] [6] Двоичные данные также могут использовать более эффективный формат base64 как <[ b64... ]> . 8-битная проблема также неявно решена, поскольку большинство развертываний используют UTF-8. В целом, NSPropertyListGNUstepFormat приносит выразительность и компактность удобного для чтения человеком текстового формата наравне с форматом XML Apple.<*DYYYY-MM-DD HH:MM:SS +ZZZZ>
GNUstep также имеет свой собственный двоичный формат, NSPropertyListGNUstepBinaryFormat , реализованный в NSSerialization . Этот формат определяется рекурсивно, как и текстовые форматы, с однобайтовым маркером типа, предшествующим некоторым данным. Форма интернирования строк поддерживается через переключатель GS-extension shouldBeCompact . [7]
В GNUstep есть два относительно независимых обработчика plist: CFPropertyList в libs-core-base (CoreFoundation) и NSPropertyList в libs-base (Foundation Kit). Оба поддерживают двоичные и XML-формы, используемые macOS, в некоторой степени, но последний намного более полный. Например, два специфичных для GNUstep формата обрабатываются только в последнем. [8]
GNUstep предоставляет набор инструментов командной строки plist на основе NSPropertyList , включая версию pl [9] и defaults [4] .
Хотя macOS также может читать формат NeXTSTEP, Apple откладывает его в сторону в пользу двух новых собственных форматов, один на основе XML, а другой — двоичный. У Apple также есть частично совместимый формат JSON ( NSJSONSerialization ).
В Mac OS X 10.0 формат NeXTSTEP был объявлен устаревшим , и был представлен новый формат XML с открытым DTD , определенным Apple . Формат XML поддерживает не-ASCII символы и хранение объектов NSValue (которые, в отличие от формата списка свойств ASCII GNUstep, формат списка свойств ASCII Apple не поддерживает). [10]
Однако, поскольку файлы XML не являются наиболее эффективным средством хранения, Mac OS X 10.2 представила новый формат, в котором файлы списков свойств хранятся как двоичные файлы. Начиная с Mac OS X 10.4 , это формат по умолчанию для файлов настроек. В Mac OS X 10.7 была введена поддержка чтения и записи файлов в формате JSON . Однако JSON и списки свойств не полностью совместимы друг с другом. Например, списки свойств имеют собственные типы даты и данных, которые формат JSON не поддерживает. И наоборот, JSON допускает null
значения, в то время как списки свойств не поддерживают явные значения NULL.
Старый инструмент по умолчанию от NeXTSTEP остается доступным. Команда /usr/libexec/PlistBuddy предоставляет интерактивный редактор plist. Он также может быть написан на скрипте. [11]
Утилиту plutil (представленную в Mac OS X 10.2 ) можно использовать для проверки синтаксиса списков свойств или преобразования файла списка свойств из одного формата в другой. Она также поддерживает преобразование plist в объектные литералы Objective-C или Swift. [12] Как и Cocoa NSPropertyListSerialization, на котором она построена, она принимает входные данные «старого стиля», но не преобразует их в этот тип. (Cocoa NSSerializer до Mac OS X 10.2 выдает выходные данные старого стиля.)
Утилита pl представлена в Mac OS X v10.5. Она принимает любые входные данные и пытается сгенерировать plist "старого стиля". [13] [a] Как и версия GNUstep, она, по-видимому, использует свойство description типов Foundation, найденных в plist, которые Apple указала для создания допустимых plist старого стиля. [b]
Что касается внутренних компонентов, Apple предоставляет парсер с открытым исходным кодом для старого стиля, XML и двоичных форматов в своем коде C Core Foundation как CFPropertyList. Однако все утилиты и большинство частей системы используют парсер с закрытым исходным кодом NSPropertyList из Obj-C Foundation Kit. Реализация Swift имеет открытый исходный код, но не гарантирует идентичности.
Списки свойств XML и JSON можно редактировать вручную в любом текстовом редакторе. Кроме того, Apple предоставляет поддержку в Xcode для редактирования списков свойств в иерархическом просмотрщике/редакторе, который может обрабатывать plist, отформатированные в двоичном формате или XML , но не JSON . Начиная с Mac OS X 10.4 , Apple предоставляет интерфейс AppleScript для чтения файлов списков свойств через приложение System Events. Начиная с Mac OS X 10.5 , Apple предоставляет интерфейс AppleScript для редактирования, создания и записи файлов списков свойств. [14]
Для формата XML теги, соответствующие классы Foundation и типы CoreFoundation, а также форматы хранения данных следующие:
Формат двоичного файла документирован в блоке комментариев в исходном файле кода Core Foundation C ( CF/CFBinaryPList.c ) для реализации Apple с открытым исходным кодом двоичных списков plist в своей библиотеке Foundation. [15] Apple описывает реализацию как непрозрачную в своей документации на странице руководства plist(5), [16] что означает, что полагаться на формат не рекомендуется. В формате двоичного файла магическое число (первые несколько байтов файла, которые указывают, что это допустимый файл plist) — это текст bplist , за которым следуют два байта, указывающие версию формата.
Двоичный файл может хранить некоторую информацию, которая не может быть захвачена в форматах файлов XML или JSON. Двоичные типы массива, набора и словаря состоят из указателей — записей objref и keyref — которые индексируют таблицу объектов в файле. Это означает, что бинарные списки plist могут фиксировать тот факт, что, например, отдельный массив и словарь, сериализованные в файл, оба имеют один и тот же элемент данных, сохраненный в них. Это не может быть захвачено в XML-файле. Преобразование такого двоичного файла приведет к тому, что копия элемента данных будет помещена в XML-файл. Кроме того, двоичный файл имеет тип UID, который используется для идентификации элементов данных при сериализации. Полный список данных, которые могут быть сохранены, взятый из исходного файла кода C, выглядит следующим образом:
Обратите внимание на примечание v"1?"+ во многих типах. Это означает, что байт маркера встречается только в файлах с версией формата не ниже магического числа "1?". Точный способ их разбора более туманен, чем способ разбора устаревших типов, поскольку реализация CFBinaryPlist обрабатывает только версию "0?". На практике эти типы никогда не встречаются, поскольку NSKeyedArchiver уже способен захватывать эту информацию.
За таблицей объектов следует таблица смещений, за которой следует трейлер, содержащий информацию о размере и местоположении двух таблиц.
Поскольку списки свойств не охватывают всю информацию и типы данных, необходимые для описания произвольного объекта, часто выполняется дополнительный уровень кодирования и декодирования. Спецификация OpenStep абстрагирует операцию сериализации любого NSObject по протоколу NSCoding . Любой класс, реализующий этот протокол, может иметь свои экземпляры, сериализованные подклассом NSCoder в какой-либо другой формат. [18] Существуют два основных кодировщика для сериализации объектов в plist:
Помимо прочего, использование архиватора позволяет кодировать новые типы данных без изменения самого формата plist, и это предпочтительный способ для Apple кодировать такие вещи, как NSSets и значения null. Разбор форматов оказывается немного сложнее, поскольку необходимо следовать еще одному слою даже для некоторых классов, которые, как предполагалось, должны поддерживать plist. Как и в двоичном формате, который также имеет таблицу объектов, в NSKeyedArchiver можно создавать циклические ссылки . Поскольку в XML нет типа данных UID, целые числа хранятся в словаре под ключом "CF$UID". [19]
Apple публикует NSKeyedArchiver с открытым исходным кодом в Swift Corelibs Foundation; как и закрытый исходный код Apple Foundation, он ограничивает выходные форматы только двоичными и XML. Он также имеет несколько тестовых случаев, показывающих результаты сериализации. [20] GNUstep также имеет совместимую реализацию, которая не ограничивает выходные форматы. [21]
Не существует единого стандартизированного языка путей для списков свойств, подобного XPath для XML, но существуют неформальные соглашения, используемые различными программами.
(id) -[NSObject(NSKeyValueCoding) valueForKeyPath:]
Ни один из форматов не может выразить ключ, содержащий в себе символ-разделитель.
Хотя файлы plist наиболее известны в системах Apple или Darwin, включая iOS и macOS, они также присутствуют на компьютерах Windows, когда установлено программное обеспечение Apple, такое как iTunes [22] или Safari [23] . В Windows файлы обычно являются двоичными файлами, [24] хотя некоторые приложения могут генерировать файлы PLIST в других форматах.
В Windows файлы Apple plist хранятся в домашнем каталоге пользователя в %USERPROFILE%\AppData\Roaming\Apple Computer . Эти файлы plist в Windows обычно хранят настройки и другую информацию, а не используют реестр Windows.
Возможности редактирования файлов PLIST в Windows не столь обширны, как в macOS. Если файл в формате XML или JSON, то с осторожностью можно использовать текстовый редактор, например Notepad++ . Apple поставляет plutil.exe в своем пакете "Apple Application Support" (который является частью iTunes ), и он идентичен своему аналогу в macOS.
Представленная в 2006 году и впервые выпущенная с NetBSD#4.0 (2007), библиотека proplib может использоваться для сериализации данных между ядром и пользовательским пространством. Она реализует часть языка XML plist. [25]
Одним из примеров использования proplib является вторая версия фреймворка sysmon envsys для мониторинга системы .
Библиотека NetBSD proplib также была перенесена в DragonFly в 2010 году и доступна с версии DragonFly BSD#2.8 . [26]
plistlib
модуль для чтения и записи файлов plist в формате XML от Apple или в двоичном формате (начиная с версии Python 3.4). [28] ProperTree — кроссплатформенный редактор, использующий эту библиотеку. [29]plist
пакет, который поддерживает четыре типа plist: OpenStep text, GNUStep text, Apple XML и Apple Binary. Он также обрабатывает UID в XML и двоичных форматах. [2]description
Obj-C Foundation NSData
есть баг, поскольку он возвращает представление словаря. В Swift Foundation с открытым исходным кодом такой проблемы нет.Когда Unmarshal встречает список свойств OpenStep, он переходит в режим расслабленного синтаксического анализа: списки свойств OpenStep могут хранить только обычные старые данные в виде строк, поэтому мы попытаемся восстановить целочисленные, с плавающей точкой, логические значения и значения даты везде, где они необходимы.
Тип данных CF$UID в листинге 2 представляет собой словарь с одним ключом ("CF$UID"), за которым следует целое число (такую компоновку вы увидите, когда список свойств будет представлен в XML; в необработанном двоичном формате тип данных "UID" является отдельной сущностью, не требующей структуры словаря). Эти типы данных представляют собой ссылку на другую сущность в массиве "$objects". Номер CF$UID указывает положение массива.