Быть или не БИТ (или инструментарий для работы с двоичными данными).
Самое ценное, что есть в нашей жизни это дети и идеи – потому что они продолжают жить после нас. Эта статья попытка помочь реализовать Ваши идеи, разбивающиеся о стену неспособности работать из 1С с бинарными данными:)
Я, к счастью, все свои идеи по работе с бинарниками реализовал, и в процессе родился некий набор инструментов, который как мне кажется, может помочь многим ищущим программистам. Вот в этой статье я и хочу эти инструменты презентовать.
Первое и главное, о чем хочу сказать — это внешние компоненты. Они есть и широко используются и более того их нужно использовать. Но у всех внешних компонент есть одно непременное требование – нужно чтобы они были. Для стационарной конфигурации это хорошо, но если Вы пишите внешний отчет. Такой отчет должен работать всегда и по возможности везде, независимо от наличия тои или иной ВК-шки, ее версии, необходимости и возможности зарегистрировать и т.д. Да и пристегивать ради трех-пяти команд в Вашей обработке внешнюю компоненту просто не красиво.
Конечный пользователь не должен, я считаю, заморачиваться чем либо кроме Вашего продукта в действии. Дополнительное обслуживание и настройка (как бы просты с точки зрения разработчика они не были) не украшают и не упрощают Ваш продукт. Предполагаю, что последнее утверждение вызовет полемику, но такое вот у меня имхо – чем проще внешне, тем лучше для пользователя — так уж воспитали.
Ну а теперь непосредственно об инструментах работы с бинарными файлами. Естественно, что раз 1С 7.7 работать с ними без посторонней помощи не может, то нужно у кого-то помощи попросить. С моей точки зрения, для сохранения универсальности и всеядности инструмента, он должен быть всегда и везде, так чтобы о его наличии, нам было известно так же точно, как и о том, что на компьютере, исполняющем нашу обработку будет стоять 1С. Хорошо подходит Microsoft Script Control, который стандартно устанавливается на все Windows, начиная с 2000. Ну и конечно, стандартный и любимый класс ADODB.Stream, также плоть от плоти Windows.
Собственно для работы непосредственно с бинарными файлами нам нужен самый первичный инструментарий:
- Прочитать байт в нужной позиции
- Добавить произвольный байт в конец файла
- Заменить байт в нужной позиции на любой нужный нам
- Прочитать бинарный файл полностью и вернуть байтовый поток
- Создать бинарный файл из потока нужных байтов
Создание таких простых инструментов не представляет особой сложности, но сложность здесь в самой 1С, а точнее в той форме представления байтов, которая может быть интерпретирована, обработана и сохранена в 1С. То есть формат обмена между бинарными файлами и внутренними переменными 1С и постоянными хранилищами базы. Так как 1С абсолютно не понимает нулевого байта (00000000) и не имеет строкового представления этой последовательности, а байт этот очень популярен в бинарных файлах, мы не можем без предварительной обработки загрузить содержимое бинарного файла в текстовую строку. При сохранении в базе длинных строк 1С дополнительно обрезает все «пустые» символы (пробелы, табуляции и т.п.) в конце строки, что для нас, также мягко говоря, не удобно. Вот здесь и начинаются варианты. Есть старый добрый Hex формат – представления байта шестнадцатеричным числом. Формат хорош наглядностью и удобством обработки, но тратит на один бинарный байт два строковых байта (16#k8SjZc9Dxk2 = 256). То есть при хранении и обработке мы удваиваем исходный размер. Для небольших фалов это не критично по объему и скорости обработки, но если размер файла велик, то неудобства Hex формата становятся явными и здесь хочется что-то очень изменить.
Но если 1С не может предоставить нам полноценный 256-ричный формат можно использовать не столь расточительный как 16-ричный формат 64-ричный — так называемый Base64, используя 6-битные структуры и 64 символа он увеличивает размер исходного бинарного файла всего на 25-30%. Это, несомненно, намного более удобно при хранении, но не столь удобно при обработке. Проблема обработки Base64 состоит в том, что один символ Base64 соответствует не 8-битному, а 6-битному числу, а это значит, что для извлечения нужного байта, нам нужно декодировать всю последовательность Base64 в 8-битные единицы до нужного нам байта.
Hex напротив очень удобен для обработки, так как любые 2 Hex символа переведенные из 16- ричной системы в двоичную сразу дадут номер байта, все байты читаются через два символа, легко заменяются и находятся по номеру.
Таким образом, я так и не смог выбрать идеального формата для хранения и обработки бинарных файлов в 1С и остановился на том, что для обработки лучше пользовать Hex, а для хранения Base64. Соответственно пришлось создать двойной инструментарий для чтения и записи бинарных файлов отдельно для двух форматов.
С учетом всех необходимых инструментов и их функционала кода для реализации моего набора инструментов потребовалось довольно много, поэтому не будем засорять текст. Внешняя обработка BinaryFuncs.ert находится в приложении и содержит как полный инструментарий по работе с Hex и Base64 потоками, так и несколько процедур, иллюстрирующих применение библиотеки бинарных функций. Не советую загружать побайтно большие файлы, функция и процедура побайтной загрузки на практике слишком медленно обрабатывает файл и дождаться окончания загрузки даже 5 килобайтного файла кажется не реальным.
Вопрос о хранилище файлов прямо в базе 1С опять таки дискуссионный и главный аргумент против это то что 1С в принципе не имеет средств для этого, да и излишняя перегрузка базы второстепенными данными не пойдет на пользу ни удобству ни скорости работы. Минусы очевидны, но есть и плюсы. Во первых бинарное содержимое сохраняется при выгрузке и восстанавливается при загрузке базы, то есть можно упростить процесс обслуживания такой базы. Опять же проще работать с УРИБ, проще обновлять файлы новыми версиями (особенно если правила размещения и наименования дополнительных бинарных файлов базы не четкие).
Выбор в любом случае за Вами, а я лишь попытался сделать хранение двоичных файлов в базе более удобным.
Основная идея лежит не в размещении двоичных данных непосредственно в реквизите справочника или документа, а в создании отдельного справочника – хранилища бинарных данных. Этот справочник содержит в едином или разных форматах бинарные реквизиты прочих элементов и документов, ну и собственно это позволяет нам упростить и ускорить обработку основных объектов. Демонстрационная конфигурация по работе с двоичными файлами и организации их хранения непосредственно в базе 1С также находится в приложении. В принципе она содержит (пусть и не в компактном виде) функции, используемые в BinaryFuncs.ert для работы с Base64 потоками. Hex кодировка не используется, так как требование к компактному хранению данных в информационной базе является доминирующим, а Hex обеспечивает двойное увеличение исходного размера файла при хранении.
Для иллюстрации возможностей внешних компонент в демо конфигурации используется внешняя компонента BinFiles.dll. Она однозначно превосходит по скорости обработки и компактности хранения как функции Vbs, так и сам формат Base64. Но думаю Вам самим будет любопытно сравнить. Напомню лишь о разрешенном некоммерческом использовании компоненты. Сама библиотека, а также описания и обработка к ней, находятся в папке с базой конфигурации.
В самой демонстрационной базе 3 справочника. Один — универсальное хранилище бинарных данных, второй — справочник содержащий бинарные элементы формата Base64, третий — включает данные в формате BinFiles. Есть еще документ, который может принимать в качестве реквизита бинарный файл картинки любого формата.
Если база скульная, то лучше бин.файлы хранить в собственной(не 1с-овской) табличке, а в 1С хранить только id . А загружать и выгружать файлы например с помощью класса 1С++ BinaryData.
BinFiles.dll… Напомню лишь о разрешенном некоммерческом использовании компоненты.
ну, лучше юзать функционал из 1с++, у неё нет ограничений
ещё один интересный вариант: штатный виндовый ком-объект SAPI.spFileStream из спич-апи (казалось бы — при чём здесь спич-апи? ))) )
(2) andrewks, SAPI.spFileStream действительно интересный вариант. А BinFiles.dll — демонстрационный пример, к тому-же очень неплохо сжимающий двоичный поток в строковой, из соображений компактности вполне разумный.
По поводу же некоммерческого использования есть условие разработчика связаться с ним при намерении использовать коммерчески. Гемор конечно, но не факт что это будет платно:)
Саму строку хранишь в блобе ? Не комильфо.
Для скуля проще отдельную табличку и как varbinary в неё.
На практике врят ли пригодится именно в таком виде.
http://www.forum.mista.ru/topic.php?id=390858
Проще через 1cpp +riq_sql слепить
Пример тут
блин, нужно поработать с файлом больше 2Gb — эта компонента не подходит 🙁
чем можно заменить?
(6) Yury1001, Вот уж не знаю… Может объем ОЗУ меньше 2Гб. Теоретически ADODB ограничений по объему файлов не имеет, думаю здесь только физический предел в свободной DDR.
В этой связи встречал что SAPI.spFileStream не грузит файл полностью в ОЗУ. Можете попробовать этим классом.