Для работы с двоичными данными используются такие объекты встроенного языка, как Поток, ФайловыйПоток, ПотокВПамяти, ЧтениеДанных, ЗаписьДанных, БуферДвоичныхДанных и др. С помощью этих объектов можно как организовывать последовательную работу с большими объемами двоичных данных, так и осуществлять произвольный доступ к относительно небольшим двоичным данным целиком в оперативной памяти.
Общая схема работы с двоичными данными такова: сначала данные из файла поступают в объект ФайловыйПоток (или ПотокВПамяти). Из потока с помощью объекта ЧтениеДанных можно либо получить объект БуферДвоичныхДанных (прочитать в него заданное количество байтов из потока), либо разделить поток на части одинакового размера (РезультатЧтенияДанных) и каждую из них обрабатывать некоторым образом.
В обратную сторону все работает аналогично: в буфер двоичных данных можно записать какие-то данные. В объект ЗаписьДанных можно записать либо БуферДвоичныхДанных, либо РезультатЧтенияДанных. А затем ЗаписьДанных можно сразу связать с потоком и с конечным файлом. Таким образом все будет записано в конечный файл.
Поясним назначение некоторых объектов.
Для работы с данными, расположенными на диске или в памяти, предназначены объекты ФайловыйПоток и ПотокВПамяти. Это специализированные версии типа Поток. Данный объект не имеет конструктора, а получить экземпляр объекта можно при помощи различных методов других объектов.
Потоки предназначены для последовательного чтения/записи больших объемов двоичных данных. Их преимущество заключается в том, что они позволяют работать с потоками данных произвольного объема. Но вместе с тем они предоставляют лишь базовые возможности работы, такие как чтение из потока, запись в поток и изменение текущей позиции.
Потоки можно сконструировать по имени файла или получить из других объектов, например из объектов ДвоичныеДанные, HTTPЗапрос, ВложениеСистемыВзаимодействия и др.
Объект ЧтениеДанных можно сконструировать на основании потока, двоичных данных или на основании имени файла. Этот объект позволяет уже читать отдельные байты, символы, числа. С его помощью можно прочитать строку с учетом кодировки или прочитать данные до некоторого известного заранее маркера. Объект ЗаписьДанных конструируется аналогичным образом, но занимается не чтением, а записью данных. Поскольку эти объекты читают/пишут данные из/в потоки, то они также делают это последовательно, что позволяет работать с потоками произвольного объема.
Объект БуферДвоичныхДанных можно получить из объекта ЧтениеДанных, записать в ЗаписьДанных. Глобальный контекст содержит также функции получения его из различных строк, из двоичных данных и др.
Главное отличие этого объекта от рассмотренных выше заключается в том, что он предоставляет не последовательный, а произвольный доступ к данным и позволяет изменять их по месту.
Все данные этого объекта полностью находятся в оперативной памяти. Поэтому, с одной стороны, он предназначен для анализа и редактирования не очень больших объемов двоичных данных. Но, с другой стороны, дает удобные возможности для произвольного чтения и записи байтов, представленных числами, для разделения буфера на несколько частей и объединения нескольких буферов в один, а также для получения части буфера указанного размера.
Также буфер двоичных данных позволяет выполнять побитовые логические операции И, ИЛИ, ИНЕ и другие. Аналогичные функции, которые позволяют удобно выполнять побитовые операции с целыми числами, есть и в глобальном контексте.
В заключение теоретической части необходимо сказать о том, что многие объекты: ДвоичныеДанные, Поток, ФайловыйПоток, ПотокВПамяти, ЧтениеДанных, ЗаписьДанных, РезультатЧтенияДанных – имеют пары синхронных и асинхронных методов. Например: Записать() – НачатьЗапись(), Закрыть() – НачатьЗакрытие() и т. п. Асинхронные методы нужны для обеспечения возможности одинаковой работы и в тонком клиенте, и в веб-клиенте. Потому что браузеры используют асинхронную модель работы.
Синхронные методы необходимы для работы в контексте сервера. Потому что на сервере используется только синхронная модель работы. Дальше в наших примерах мы будем выполнять все манипуляции с двоичными данными на сервере и, соответственно, будем использовать синхронные методы.