Документация Engee

Регистрация нового формата

Регистрация нового формата осуществляется путем его добавления

add_format(fmt, magic, extension, libraries...)

в реестр FileIO. Рекомендуется поэкспериментировать с этой задачей локально, убедиться, что все работает, и лишь затем отправлять запрос на вытягивание. Для внесения необходимых изменений потребуется pkg> dev FileIO.

Прежде чем подробно рассматривать аргументы add_format, приведем реальный пример, который можно использовать для регистрации пакета ввода-вывода для одного из форматов изображений Netpbm.

add_format(format"PPMBinary", "P6", ".ppm", [:Netpbm => UUID("f09324ee-3d7c-5217-9330-fc30815ba969")]

Если говорить кратко, что файлы в этом формате обычно имеют расширение .ppm, содержимое файла обычно начинается с «P6» (последовательность байт [0x50, 0x36]), и эти файлы могут быть считаны и записаны пакетом Netpbm. (UUID является уникальным идентификатором Julia для данного зарегистрированного пакета и может быть получен из файла Project.toml.)

Аргумент fmt

fmt имеет тип DataFormat, который удобнее всего создавать как format"IDENTIFIER". Если этот формат файла ранее не поддерживался, вы можете создать IDENTIFIER самостоятельно — внешнего стандарта не существует, это просто «метка», используемая внутренним образом в FileIO и его вспомогательных процедурах. Как правило, следует выбирать такой вид, чтобы можно было легко догадаться, к какому формату он относится. Вот примеры некоторых существующих fmt.

Аргумент magic

magic обычно содержит магические байты, идентифицирующие формат. Хотя формат файла иногда можно определить по расширению (например, pic.png, скорее всего, является файлом изображения PNG), по сути, имя файла является тем, что может быть изменено пользователем, поэтому оно может не иметь никакого отношения к содержимому файла. Более того, существует множество примеров, когда два или более различных формата используют одно и то же расширение, что приводит к неоднозначному пониманию характера файла. Является ли файл .gbv файлом Genie Timeline или PCB-файлом CAD? Является ли этот файл .fst аудиофайлом, файлом игры-головоломки или файлом сериализованного фрейма данных на языке R?

Для однозначного определения файла разработчики хороших форматов включают в состав содержимого файла «магические байты», чтобы пользователи могли распознать или проверить формат файла. Как правило, эти магические байты являются первыми байтами в файле, хотя существует множество исключений.

Форматы, использующие распространенные расширения (например, .out) и не содержащие магические байты, не могут быть зарегистрированы в FileIO — в противном случае пришлось бы отдавать предпочтение одному конкретному формату среди всех остальных. В таких случаях пакет должен обеспечивать собственные возможности ввода-вывода без использования FileIO. Чтобы избежать конфликтов имен с FileIO, рекомендуется не экспортировать из своего пакета имена типа load и save, а использовать модульные квалификаторы типа MyPkg.load.

Некоторые форматы имеют несколько разновидностей магических байтов (которые могут, например, включать номер «версии формата»). В таких случаях magic может представлять собой список последовательностей байтов. В других случаях файлы невозможно идентифицировать по определенному набору байтов. Однако существует шаблон, который можно использовать: magic может быть функцией, которая возвращает true или false в зависимости от того, согласован ли поток ввода-вывода с форматом.

Примеры магических байтов:

  • Файлы изображений формата GIF могут иметь магические байты, соответствующие символам ASCII в "GIF87a", т. е. [0x47, 0x49, 0x46, 0x38, 0x37, 0x61]. Или они могут использовать "GIF89a", который указывает на другую версию формата GIF.

  • PLY-файлы сетки могут быть двух видов — ASCII и бинарные. Их магическими байтами являются "ply\nformat ascii 1.0" и "ply\nformat binary_little_endian 1.0", соответственно. Эти магические байты удобны для восприятия и занимают первые две строки файла.

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

Аргумент extension

Может быть строкой или списком строк. Каждая строка должна начинаться с '.'.

Пример: в формате Nearly Raw Raster Data используется [".nrrd",".nhdr"].

Аргумент libraries

Этот аргумент определяет пакет или пакеты, которые могут поддерживать ввод и (или) вывод для данного формата. Каждая спецификация пакета должна иметь вид name => uuid, где name — имя пакета (кодируется как Symbol, например :FeatherFiles), а uuid — UUID из Project.toml пакета. Первый указываемый пакет имеет наивысший приоритет. FileIO попытается использовать его для выполнения запрошенной операции и перейдет к следующему только в случае неудачи. Сбой может произойти из-за того, что у пользователя не установлен пакет или обработчик пакета выдал ошибку.

Некоторые пакеты могут поддерживать только определенные формы ввода-вывода и могут использовать LOAD и SAVE в качестве спецификаторов поддерживаемых операций. Аналогичным образом некоторые пакеты используют системные библиотеки, доступные только на определенных платформах, и могут содержать спецификатор платформы.

Если ваш пакет еще не зарегистрирован, в качестве альтернативы можно указать обработчик в виде самого модуля. В таких случаях вызов add_format, скорее всего, будет осуществляться из модуля или в REPL Julia, а не в реестре FileIO. Исключением является MimeWriter, подмодуль FileIO, который может записывать несколько форматов MIME.

Вот реальный пример (содержащийся в файле src/registry.jl FileIO) для PNG:

add_format(
    format"PNG",
    UInt8[0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a],
    ".png",
    [idImageIO],
    [idQuartzImageIO, OSX],
    [idImageMagick],
    [MimeWriter, SAVE]
)

idImageIO, idQuartzImageIO и idImageMagic — это пары name => uuid для трех различных пакетов. Пакет QuartzImageIO доступен только в системах macOS (OSX). Модуль MimeWriter (который внутренним образом доступен для FileIO) поддерживает только вывод (SAVE), но не ввод.

Примеры

Чтобы ознакомиться с дополнительными примерами, пользователям предлагается напрямую изучить реестр FileIO.