Введение

Resource fork – это форк файла в операционной системе Apple macOS, используемый для хранения структурированных данных. Это один из двух форков файла, наряду с форком данных, который хранит данные, рассматриваемые операционной системой как неструктурированные. Resource fork хранит информацию в определенном формате, включая такие детали, как растровые изображения значков, формы окон, определения меню и их содержимое, а также код приложений (машинный код). Например, файл текстового процессора может хранить свой текст в форке данных, а встроенные изображения – в resource fork того же файла. Resource fork в основном используется исполняемыми файлами, но любой файл может иметь resource fork. В технической заметке 1986 года компания Apple настоятельно рекомендовала разработчикам не помещать произвольные данные в resource fork файла. По мнению Apple, некоторые компоненты системного программного обеспечения полагаются на то, что resource fork содержит только корректную информацию Resource Manager. Resource fork был разработан и реализован программистом Apple Брюсом Хорном.

Идентификаторы ресурсов

Каждый ресурс имеет идентификатор OSType (четырехбайтовое значение), ID (знаковое 16-битное слово) и необязательное имя. Существуют стандартизированные типы ресурсов для диалоговых окон (DITL), изображений (PICT), звуков (snd) и исполняемых двоичных файлов (CODE), которые до появления процессора PowerPC без исключения хранились в ресурсной вилке. Подпрограммы для отрисовки окон хранятся в ресурсах своего типа (WDEF), а подпрограммы для отрисовки меню – в ресурсах другого типа (MDEF). Такая организация позволяла пользователям легко настраивать не только отдельные приложения, но и саму операционную систему, используя инструменты вроде ResEdit для изменения ресурсов файла приложения или любого из системных файлов. В приложении или другом коде ресурсы можно загружать, используя комбинацию их типа, ID или имени, не заботясь о том, как и где они хранятся в ресурсной вилке. Клиент получает дескриптор к загруженному ресурсу, к которому затем можно обращаться как к любым другим данным, размещенным в куче. Компонент ОС, обеспечивающий эту функциональность, – это Менеджер ресурсов. Помимо абстрагирования деталей хранения данных, Менеджер ресурсов также организует наборы открытых ресурсных вилок в стек, при этом последний открытый файл находится наверху. При попытке загрузить ресурс он сначала ищет в верхней части стека (например, в ресурсной вилке текущего документа), затем в следующей ниже (в ресурсной вилке приложения), затем в следующей (в системных ресурсных вилках). Эта организация очень эффективна: она позволяет локальным ресурсам переопределять более глобальные, расположенные ниже, например, приложение может предоставлять собственные значки или шрифты вместо стандартных системных. Она также позволяет приложению загружать ресурсы из системы, используя тот же API, что и для любых других ресурсов, не заботясь о том, где и как этот ресурс хранится; для приложения все ресурсы одинаково доступны и просты в использовании. Система резервирует определенный диапазон ID ресурсов, чтобы избежать конфликтов, которые могут возникнуть из-за этого. API Менеджера ресурсов позволяет программисту манипулировать стеком и изменять логику поиска.

Редактирование

Поскольку ресурсный вилок можно редактировать с помощью редактора ресурсов, такого как ResEdit, он может использоваться для локализации и настройки программного обеспечения. Кроме того, большинство редакторов ресурсов позволяют визуально редактировать данные. В macOS ресурсы можно использовать при разработке приложения. Однако, если приложение может потребоваться использовать в UFS, можно также настроить его так, чтобы вся вилка ресурсов была перемещена в вилку данных, используя настройку Raw Resource File. Интегрированные среды разработки, распространяемые бесплатно компанией Apple Inc., включая MPW и Apple Developer's Tools, включают компилятор под названием Rez. Для этого используется специальный язык, также называемый Rez, который можно использовать для создания ресурсной вилки путем компиляции исходного кода. Также включен декомпилятор DeRez, который можно использовать для преобразования ресурсной вилки обратно в код Rez. В структуре ресурсной вилки есть фрагмент данных, называемый «картой ресурсов», который хранит позиции элементов данных ресурсов. Это позволяет осуществлять произвольный доступ к данным ресурсов на основе определенных идентификаторов и имен. Ресурсный вилок можно рассматривать как состоящий, по сути, из двух объектов: карты ресурсов и самих данных ресурсов, но на самом деле каждый тип данных представляет собой иерархическую структуру, хранящую несколько элементов данных. Формат, в котором хранится информация в данных ресурсов, определяется на основе типов информации, известных как «типы ресурсов». Данные ресурсов часто содержат ссылки на другие типы данных. В macOS форки называются file/namedfork/forkname, например, ресурсный вилок файла IMG 0593.jpg – IMG 0593.jpg/namedfork/rsrc. Команда ls поддерживает опцию l@, которая выводит список форков файла.

Типы данных

Самые маленькие элементы, составляющие ресурсную вилку, называются типами данных. Существует несколько типов данных. После доступа к ресурсной вилке, её содержимое можно получить, прочитав его в соответствии с заранее определёнными типами данных. Размещение определений внутри программы, указывающих, как следует обрабатывать данные, также позволяет хранить ресурсы, называемые TMPL-ресурсами. Использование этого метода повышает наглядность данных при просмотре в программе, такой как ResEdit, что упрощает последующее редактирование. Поскольку платформа Macintosh изначально создавалась для процессоров Motorola (68k и PPC), данные сериализуются на диск в формате big endian. Ниже приведён список основных типов данных в алфавитном порядке.

Имя типа данных | Описание
---|---
BBIT | binary bit – Представляет один логический бит (истина или ложь). Обычно количество BBIT должно быть кратно восьми.
BOOL | boolean – Представляет логическое значение. Состоит из 2 байтов: 256 – истина, 0 – ложь.
CHAR | character – Представляет однобайтовый символ.
CSTR | C string – Представляет строку, используемую в языке программирования C: строку байтов, завершающуюся нулевым символом.
DLNG | decimal long word integer – Десятичное длинное слово (4-байтовое целое число). Представляет значения в диапазоне примерно от -2,1 миллиарда до 2,1 миллиарда.
HEXD | hex dump – Указывает, что данные от этой позиции до конца представлены в шестнадцатеричном формате. Используется для представления ресурсов кода или сжатых данных.
HLNG | long word hexadecimal – Эти данные интерпретируются как 4-байтовое шестнадцатеричное значение. Используется, в частности, для представления целых чисел, превышающих 2,1 миллиарда, таких как беззнаковые длинные значения в C.
PSTR | Pascal string – Представляет строку Pascal, где первый байт указывает длину строки.
TNAM | type name – Строка, представляющая значение, например, код создателя, который всегда имеет длину 4 байта.
RECT | rectangle – Представляет координаты углов прямоугольника (верхний, левый, нижний, правый). Всегда занимает 8 байтов.

Типы

Коды типов, представленные ниже, как и вышеуказанные типы данных, используются в качестве идентификаторов типов не только для самих форков ресурсов, но и для идентификации файлов, описания данных в буфере обмена и многого другого. Типы должны быть длиной 4 байта, поэтому типы, такие как snd и STR, фактически имеют пробел (0x20) в конце.

alis – alias Хранит ссылку на другой файл в форке ресурсов файла, у которого установлен атрибут "alias".
ALRT – alert Определяет внешний вид окна предупреждения приложения.
APPL – application Хранит информацию о приложении.
BNDL – bundle Определяет данные, такие как значок типа файла, используемый в приложении.
cicn – color icon Определяет цветной значок, используемый в данных.
clut – color look up table Определяет цветовую палитру, используемую в данных.
CNTL – control Определяет детали компонента, расположенного в окне.
CODE – code resource Хранит машинный код программы.
CURS – cursor Определяет форму монохромного курсора (квадрат 8 × 8 бит).
DITL – dialog item list Определяет компонент окна.
DLOG – dialog Определяет внешний вид диалогового окна приложения.
FREF – file reference Определяет тип файла, обрабатываемый приложением.
hfdr – icon balloon help Определяет содержимое и внешний вид всплывающей подсказки, отображаемой при наведении курсора на файл в Finder.
icl8 – 8 bit icon list Определяет значок, отображаемый в Finder.
icns – 32 bit icon list Определяет значок, отображаемый в Finder.
ICON – icon Определяет монохромный элемент, используемый в данных.
kind – file description Определяет описание типа файла.
MBAR – menu bar Определяет меню и строку меню для приложения.
MDEF – menu definition Определяет меню для приложения. Может также использоваться для определения меню со сложной структурой, например, цветовых палитр.
MENU – menu Определяет элементы меню в приложении.
MooV – movie Хранит QuickTime movie.
open – open Определяет тип файла, который приложение может открыть.
PICT – picture Хранит PICT изображение, содержащееся в файле.
PREF – preference Хранит настройки среды для приложения.
snd – sound Хранит звук, используемый в файле.
STR – string Хранит строку или шестнадцатеричные данные, используемые в файле.
STR# – string list Хранит несколько строк, используемых в файле.
styl – style Определяет информацию о стиле, такую как шрифт, цвет и размер текста.
TEXT – text Хранит текст.
TMPL – template Определяет формат данных ресурса.
vers – version Определяет версию или область использования файла.
WDEF – window definition Определяет окно для приложения. Окна неопределенной формы также могут быть определены.
WIND – window Определяет форму окна приложения.

Редакторы

ResEdit Распространяется бесплатно компанией Apple. Может использоваться для визуального редактирования ресурсных данных. Если структура данных известна, он может отображать различные типы данных в визуальном формате. Не работает на современных версиях macOS. Resorcerer Дорогой, но популярный, поскольку позволяет визуально редактировать гораздо больше типов данных, чем ResEdit. HexEdit Бинарный редактор, который чаще всего используется для редактирования форка данных, а не ресурсного форка. ResKnife Редактор с открытым исходным кодом для Mac OS X, разработка которого больше не ведется. Rezycle Инструмент для macOS, извлекающий ресурсы из ресурсного форка в отдельные двоичные файлы и преобразующий многие типы в форматы, подходящие для современной разработки. resource dasm Инструмент для извлечения ресурсов с открытым исходным кодом для macOS и Linux, также способный преобразовывать многие ресурсы в современные форматы. ResForge Редактор ресурсов для macOS, позволяющий редактировать классические файлы ресурсного форка и связанные с ними форматы. Совместим с macOS 10.14 и более поздними версиями. Работает непосредственно на 64-битных процессорах Intel и Apple Silicon.

Совместимость

Сложность программирования с ресурсными вилками привела к проблемам совместимости при доступе к другим файловым системам через протоколы совместного использования файлов, такие как AFP, SMB, NFS и FTP, при хранении на не-HFS томах или при передаче файлов другим системам другими способами (например, по электронной почте). Протокол AFP изначально поддерживает ресурсные вилки, поэтому они обычно передаются на эти тома без изменений и хранятся сервером прозрачно для клиентов. Протокол SMB поддерживает систему метаданных файлов, аналогичную форкам Macintosh, известную как альтернативные потоки данных (далее – ADSes). macOS не поддерживала хранение ресурсных вилок в ADSes на SMB-томах по умолчанию до Mac OS X v10.6. В предыдущих версиях ОС, включая обновленные версии 10.6, эту функцию можно включить, изменив параметр или создав специальный файл. Сетевые протоколы обмена файлами, такие как NFSv3 и FTP, не имеют понятия метаданных файлов, поэтому не существует способа хранения ресурсных вилок. Это также справедливо при записи на определенные типы локальных файловых систем, включая UFS, и на SMB-тома, где поддержка альтернативных потоков данных не включена. В этих случаях macOS хранит метаданные и ресурсные вилки, используя технику AppleDouble, при которой форк данных записывается как один файл, а ресурсный форк и метаданные – как совершенно отдельный файл, начинающийся с символа «.». Например: ExampleFile.psd будет содержать форк данных, а ExampleFile.psd – ресурсный форк и метаданные. Проблемы совместимости могут возникать, поскольку macOS по-разному обрабатывает хранение ресурсных вилок в зависимости от версии macOS, настроек и типа файловой системы. Например, в сети SMB с клиентами версий 10.5 и 10.6. Свежеустановленный клиент 10.6 будет искать и хранить ресурсные вилки на SMB-томе в ADSes, а клиент 10.5 (по умолчанию) будет игнорировать ADSes и использовать формат AppleDouble для обработки вилок. Если файловый сервер поддерживает как AFP, так и NFS, то клиенты, использующие NFS, будут хранить файлы в формате AppleDouble, а пользователи AFP – ресурсный форк в нативном формате. В этих случаях совместимость иногда можно обеспечить, принудительно заставляя клиентов использовать или не использовать формат AppleDouble. Многие файловые серверы, предоставляющие поддержку AFP, не поддерживают ресурсные вилки на своих локальных файловых системах. В этих случаях вилки могут храниться особыми способами, например, в специально названных файлах, специальных каталогах или даже в альтернативных потоках данных. Другая проблема заключается в сохранении ресурсных вилок при передаче файлов с использованием приложений, не учитывающих ресурсные вилки, или определенных методов передачи, включая электронную почту и FTP. Для этого были созданы такие форматы файлов, как MacBinary и BinHex. Инструменты командной строки SplitForks и FixupResourceForks позволяют вручную «сглаживать» и объединять ресурсные вилки. Кроме того, файловый сервер, стремящийся предоставить файловые системы клиентам Macintosh, должен учитывать как ресурсный форк, так и форк данных файлов; UNIX-серверы, предоставляющие поддержку AFP, обычно реализуют это с помощью скрытых каталогов. У старых приложений, написанных с использованием Carbon API, может возникнуть проблема при переносе на современные Intel Mac. Хотя Resource Manager и операционная система знают, как правильно десериализовать данные для общих ресурсов, таких как 'snd' или 'moov', ресурсы, созданные с использованием ресурсов TMPL, необходимо вручную менять местами байтами, чтобы обеспечить совместимость файлов между версиями приложения на базе PPC и Intel. (Хотя карта ресурсов и другие детали реализации используют порядок байтов big-endian, сам Resource Manager не имеет информации о содержимом общего ресурса и поэтому не может автоматически выполнять обмен байтами.) До появления Mac OS X v10.4 стандартные утилиты командной строки UNIX в macOS (такие как cp и mv) не учитывали ресурсные вилки. Чтобы скопировать файлы с ресурсными вилками, необходимо было использовать ditto или CpMac и MvMac.

Другие операционные системы

Концепция менеджера ресурсов для графических объектов, призванная экономить память, возникла в пакете OOZE на Xerox Alto в Smalltalk 76. Эта концепция сейчас широко распространена во всех современных операционных системах. Однако концепция ресурсной вилки остаётся уникальной для Macintosh. Большинство операционных систем используют двоичный файл, содержащий ресурсы, который затем "присоединяется" к концу существующего файла программы. Это решение используется, например, в Microsoft Windows, и аналогичные решения применяются в X Window System, хотя ресурсы часто хранятся в отдельном файле. Windows NT NTFS поддерживает форки (и, следовательно, может выступать в качестве файлового сервера для файлов Mac), а встроенная функция, обеспечивающая такую поддержку, называется потоком альтернативных данных. Функции операционной системы Windows (например, стандартная вкладка "Сведения" на странице "Свойства" для файлов, не относящихся к Office) и приложения Windows используют их, и Microsoft разрабатывала файловую систему следующего поколения, в которой эта функция является основой. Ранние версии BeOS реализовали базу данных в файловой системе, которую можно было использовать аналогично ресурсной вилке. Проблемы с производительностью привели к переходу в более поздних версиях к системе сложных атрибутов файловой системы. В этой системе ресурсы обрабатывались способом, несколько более похожим на Mac. AmigaOS не использует форкированные файлы. Его исполняемые файлы внутренне разделены на модульную структуру, состоящую из крупных блоков (чанков), способных хранить код, данные и дополнительную информацию. Аналогично, файлы данных и проектов имеют структуру блоков, кодифицированную в стандарте IFF. Другие типы файлов хранятся аналогично другим операционным системам. Хотя AmigaOS и не использует ресурсную вилку, она хранит метаданные в файлах, известных как информационные файлы. Информационные файлы можно идентифицировать по расширению .info; например, при сохранении проекта на диск будут сохранены два файла: MyProject и MyProject.info. MyProject будет содержать фактические данные проекта, а MyProject.info – иконку проекта, информацию о том, какая программа необходима для открытия проекта (поскольку в AmigaOS нет привязки приложений), специальные параметры проекта и любые комментарии пользователей. Информационные файлы невидимы на рабочем столе Amiga (Workbench). Иконка на рабочем столе, взятая из самого информационного файла, является метафорой интерфейса, через которую пользователь взаимодействует как с самим проектом, так и с его связанным информационным файлом. Диалоговое окно, доступное по щелчку правой кнопкой мыши на иконке, позволяет пользователю просматривать и изменять метаданные, содержащиеся в информационном файле. Информационные файлы можно рассматривать как отдельные файлы в интерфейсе командной строки или в файловом менеджере. Современные клоны AmigaOS (AROS, MorphOS и AOS4) наследуют структуру (вместе с метаданными) информационных файлов старых версий AmigaOS и также могут принимать стандартные графические файлы PNG в качестве растровых изображений иконок в своих информационных файлах. Операционные системы NeXT NeXTSTEP и OPENSTEP, их преемник macOS, и другие системы, такие как RISC OS, реализовали другое решение. В этих системах ресурсы остаются в исходном формате, например, изображения включаются в виде полных файлов TIFF вместо кодирования в какой-либо контейнер. Затем эти ресурсы помещаются в каталог вместе с исполняемым кодом и "сырыми данными". Каталог (называемый "пакетом" или "каталогом приложения") затем представляется пользователю как само приложение. Это решение обеспечивает ту же функциональность, что и ресурсная вилка, но позволяет легко манипулировать ресурсами из любого приложения – не требуется "редактор ресурсов" (например, ResEdit). В интерфейсе командной строки пакет выглядит как обычный каталог. Такой подход был невозможен в классической Mac OS, поскольку файловая система (MFS) не поддерживала отдельные каталоги каталогов. Когда поддержка каталоговых файлов была включена в Mac OS с файловой системой HFS, ресурсная вилка была сохранена. macOS сохраняет классический API-интерфейс Resource Manager в составе своих библиотек Carbon для обратной совместимости. Однако сами ресурсы теперь могут храниться в отдельных файлах данных в файловой системе, и Resource Manager скрывает это изменение реализации от клиентского кода.