1с стрразделить не определена
Средства работы с двоичными данными
Необходимо просканировать каталог с файлами, выбрать файлы с расширением ".jpg" или ".jpg" и для каждого такого файла собрать информацию об изображении. Если при анализе выяснится, что файл не соответствует формату JPEG, то такой файл следует пропустить.
Информация, которая нас интересует:
- Ширина изображения в пикселах,
- Высота изображения в пикселах,
- Глубина цвета (количество битов на один пиксел).
Краткое описание формата JPEG
Кратко опишем некоторые детали формата, существенные для решения нашей задачи. За более подробным описанием формата JPEG можно обратиться к соответствующим источникам:
Файл JPEG содержит последовательность маркеров , каждый из которых начинается с байта 0xFF, свидетельствующего о начале маркера, и байта-идентификатора. Некоторые маркеры состоят только из этой пары байтов, другие же содержат дополнительные данные, состоящие из двухбайтового поля с длиной информационной части маркера (включая длину этого поля, но за вычетом двух байтов начала маркера, то есть 0xFF и идентификатора) и собственно данных. Такая структура файла позволяет быстро отыскать маркер с необходимыми данными (например, с длиной строки, числом строк и числом цветовых компонентов сжатого изображения).
Решение
Создадим функцию, которая будет сканировать файл, определять его формат и выделять нужную нам информацию.
Важно, что для корректного разбора маркеры необходимо читать последовательно, один за другим, т.к. байты, совпадающие с маркером могут быть в содержимом фрагментов.
Теперь, когда мы написали основную функцию для анализа JPEG-файла, напишем вспомогательную функцию - ПрочитатьМаркер , которая читает очередной маркер и возвращает информацию о нем:
- РазмерСекции : размер секции, начало которой отмечает маркер
- ЭтоОписаниеИзображения : признак того, что секция, отмеченная маркером, содержит нужную нам информацию об изображении.
И, наконец, соберем всё вместе и напишем функцию, которая будет анализировать все файлы в заданной папке и выдавать полученную информацию в виде таблицы.
Вы можете скачать приложенную конфигурацию прямо сейчас
Постановка задачи
Ответ от сервиса будет иметь следующий вид:
В качестве обработчика для метода создаем в модуле сервиса функцию ДляВсех_Get :
Создаем новую общую форму. На форму добавляем реквизиты типа Строка:
Далее добавляем элементы управления:
Создаем обработчик команды:
Вся работа по запросу сервиса и отображению результата выполняется в серверной функции ВыполнитьЗапрос :
Функции для работы со строками в 1С 8.2 и 8.3
Строка
Функция Строка(x) возвращает текстовое представление переданного ей значения “x”.
СтрДлина
Функция СтрДлина(x) вычисляет количество символов в строке “x”, учитывая пробелы и ничего не значащие символы.
СокрЛП, СокрЛ, СокрП
Функции СокрЛП(x), СокрЛ(x) и СокрП(x) убирают пробелы и ничего не значащие символы у переданной строки “x” с обеих сторон, слева и справа соответственно.
Лев, Прав, Сред
Функции Лев(x, y) и Прав(x, y) возвращают количество символов “y” с левого или правого края переданной им строки “x”. А функция Сред(x, y, z) возвращает количество символов “z” из указанного места “y” переданной строки “x”.
ВРег, НРег, ТРег
Сообщить(ТРег("Каждое слово с заглавной буквы")); //Каждое Слово С Заглавное БуквыНайти
Функция Найти(x, y) возвращает номер первого символа первого вхождения подстроки “y” в строку “x”, если, конечно, такое вхождение найдено (при этом нумерация начинается с 1). Если же вхождений не найдено, то функция возвращает 0.
СтрЧислоВхождений
Функция СтрЧислоВхождений(x, y) возвращает количество вхождений подстроки “y” в строку “x”.
СтрЗаменить
Функция СтрЗаменить(x, y, z) позволяет в указанной строке “x” заменить все вхождения одной подстроки “y” на другую “z”, результатом выполнения функции будет строка с проведенными заменами.
Сообщить(СтрЗаменить("тест1,тест2,тест3,тест4", ",", " ")); //тест1 тест2 тест3 тест4ПустаяСтрока
СтрЧислоСтрок
Функция СтрЧислоСтрок(x) возвращает количество строк в многострочном тексте “x”.
МногострочныйТекст = СтрЗаменить("тест1,тест2,тест3,тест4", ",", Символы.ПС); //тест1 тест2 тест3 тест4СтрПолучитьСтроку
Функция СтрПолучитьСтроку(x, y) возвращает строку с номером “y” из многострочного текста “x”.
МногострочныйТекст = СтрЗаменить("тест1,тест2,тест3,тест4", ",", Символы.ПС); //тест1 тест2 тест3 тест4 Сообщить(СтрПолучитьСтроку(МногострочныйТекст, 2)); //тест2Символ, КодСимвола
Символы
Это не функция, а набор наиболее часто используемых специальных символов, состоит из:
ЗначениеВСтрокуВнутр, ЗначениеИзСтрокиВнутр
Функция ЗначениеВСтрокуВнутр(x) возвращает системное строковое представление значения “x”. Функция ЗначениеИзСтрокиВнутр(x) проделывает обратную операцию и возвращает значение, полученное из строкового системного представления “x”. Обе эти функции используются для сохранения функциональной совместимости с версией 7.7. Использование для каких-либо других целей не рекомендуется. В новых версиях платформы данные функции не работают (хотя их описание присутствует в справке).
ВвестиСтроку
Мы реализовали ряд низкоуровневых инструментов для работы с двоичными данными. Теперь вы можете решать такие задачи как:
- Взаимодействие со специализированными устройствами по двоичному протоколу;
- Разбор файлов и манипуляция файлами различных форматов;
- Конвертация текстовых данных напрямую в двоичные данные, например, для отправки отчетов;
- Работа с двоичными данными в памяти.
Ранее в платформе существовал ряд методов для работы с файлами и тип ДвоичныеДанные. Но они не позволяли каким-либо простым способом проанализировать внутреннее содержимое или модифицировать его. Все действия выполнялись над всеми данными целиком. Единственная операция, которая была возможна над частью данных это разделение файла на части и склейка обратно.
Теперь платформа предоставляет инструменты как для последовательной работы с большими объёмами двоичных данных, так и для произвольного доступа к относительно небольшим двоичным данным целиком в оперативной памяти.
Основные типы для последовательной работы с данными
Назначение и взаимную связь новых объектов удобнее всего посмотреть на конкретном примере. Пример разбивает wav файл на одинаковые части размером 1000 байт.
На схеме показана последовательность использования объектов встроенного языка, соответствующая листингу.
Пример: Разбить WAV-файл на части
Основу для работы с двоичными данными составляет группа новых типов, которую можно обозначить словом «потоки». Таких типов три: Поток, ФайловыйПоток и ПотокВПамяти. В примере используется один из них, ФайловыйПоток, но остальные работают, по большому счёту, аналогично.
Потоки предназначены для последовательного чтения/записи больших объемов двоичных данных. Их преимущество заключается в том, что они позволяют работать с потоками данных произвольного объёма. Но вместе с этим они предоставляют лишь базовые возможности работы, такие как чтение из потока, запись в поток и изменение текущей позиции.
Потоки можно сконструировать по имени файла или из объекта ДвоичныеДанные. В примере поток конструируется по имени файла (ФайловыеПотоки.ОткрытьДляЧтения(ИмяФайла)) одним из методов объекта МенеджерФайловыхПотоков. Это новый способ конструирования, дальше мы расскажем о нём.
Затем в примере, для того, чтобы иметь более широкие возможности работы, из файлового потока конструируется объект ЧтениеДанных (Новый ЧтениеДанных(ПотокИсходный)). Этот объект позволяет уже читать отдельные байты, символы, числа. С его помощью можно прочитать строку с учётом кодировки, или прочитать данные до некоторого известного заранее маркера. Этот объект имеет своего «антипода», ЗаписьДанных, который конструируется аналогичным образом, но занимается не чтением, а записью данных. Поскольку эти объекты читают/пишут данные из/в потоки, то они также делают это последовательно, что позволяет работать с потоками произвольного объёма.
В примере ЧтениеДанных используется с двумя целями. Во-первых, для того, чтобы прочитать и изменить заголовок файла, а во-вторых, для того, чтобы разделить файл на несколько частей.
Заголовок файла получается в виде объекта БуферДвоичныхДанных. Это важный объект, но о нём мы скажем чуть позже. А тело файла делится на части равного размера (ЧтениеДанных.РазделитьНаЧастиПо(1000)), которые получаются в виде объектов РезультатЧтенияДанных. Этот тип никаких особенных возможностей не предоставляет, а в основном просто хранит прочитанные данные.
Далее в примере для каждой такой части файла создаётся ФайловыйПоток для записи, и на его основе конструируется ЗаписьДанных. Запись данных записывает в поток новый заголовок, новое тело, и закрывает его. В результате, по окончании цикла, получается набор из нескольких файлов.
Побайтовые операции
В примере заголовок файла читается в объект БуферДвоичныхДанных (ПрочитатьВБуферДвоичныхДанных(44)). Главное отличие этого объекта от рассмотренных выше заключается в том, что он предоставляет не последовательный, а произвольный доступ к данным, и позволяет изменять их по месту.
Все данные этого объекта полностью находятся в оперативной памяти. Поэтому, с одной стороны, он предназначен для анализа и редактирования не очень больших объёмов двоичных данных. Но с другой стороны даёт удобные возможности для произвольного чтения и записи байтов, представленных числами, для разделения буфера на несколько частей и объединения нескольких буферов в один, а также для получения части буфера указанного размера.
В качестве иллюстрации возможностей буфера двоичных данных можно привести пример поворота картинки на 90 градусов.
Пример: поворот изображения
Синхронная и асинхронная работа
Потоки (Поток, ФайловыйПоток, ПотокВПамяти), ЧтениеДанных, ЗаписьДанных, РезультатЧтенияДанных имеют пары синхронных и асинхронных методов. Например, Записать() – НачатьЗапись(), Закрыть() – НачатьЗакрытие().
Асинхронные методы нужны для того, чтобы иметь возможность одинаковой работы и в тонком клиенте, и в веб-клиенте. Потому что браузеры используют асинхронную модель работы.
Синхронные методы необходимы для работы в контексте сервера. Потому что на сервере используется только синхронная модель работы.
Менеджеры и асинхронные конструкторы
В дополнение к перечисленным объектам мы реализовали ещё два менеджера, которые существуют в единственном экземпляре, и доступны через свойства глобального контекста БуферыДвоичныхДанных и ФайловыеПотоки.
МенеджерБуферовДвоичныхДанных позволяет выполнять какие-либо операции с буферами без привязки к контексту конкретных экземпляров этих объектов. Например, сейчас с его помощью можно соединить несколько буферов в один.
Конечно, одноимённый метод Соединить() есть и у самого объекта БуферДвоичныхДанных. С его помощью можно соединить данный буфер с другим. Но для этого нужно использовать контекст данного буфера, что бывает не всегда удобно.
МенеджерФайловыхПотоков мы создали для других целей. Для потоков, как мы уже говорили, необходима возможность как синхронной, так и асинхронной работы. И если для синхронных методов мы сделали их асинхронные аналоги, то для конструкторов такой способ не подходит. Конструкторы объектов могут работать только синхронно. Поэтому для того, чтобы была возможность асинхронного конструирования, мы реализовали менеджер с асинхронными методами, которые, по сути, разными способами конструируют объект ФайловыйПоток.
А для красоты и симметричности мы добавили ему аналогичные синхронные методы. Чтобы была возможность упростить запись, и вместо конструктора с четыремя параметрами:
использовать подходящий метод с одним параметром:
В качестве иллюстрации новых возможностей работы с двоичными данными хочется привести ещё два листинга. Они показывают реализацию актуальной задачи, о которой нас часто спрашивали.
Мы расширили набор функций, предназначенных для работы со строками. Мы это сделали для того, чтобы дать вам более развитые инструменты для разбора строковых данных. Новые функции будут удобны и полезны в технологических задачах анализа текста. В задачах, связанных с разбором текста, который содержит данные в форматированном виде. Это может быть анализ каких-то файлов, полученных от оборудования, или, например, анализ технологического журнала.
Все действия, которые выполняют новые функции, вы могли выполнять и раньше. С помощью более или менее сложных алгоритмов, написанных на встроенном языке. Поэтому новые функции не дают вам каких-то принципиально новых возможностей. Однако они позволяют сократить количество кода, сделать код более простым и понятным. А кроме этого они позволяют ускорить выполнение действий. Потому что функции, реализованные в платформе, работают, конечно же, быстрее, чем аналогичный алгоритм, написанный на встроенном языке.
Функция форматирования СтрШаблон()
<Шаблон> - это строка, в которую нужно подставить представления параметров.
<Значение1> , . <Значение10> - это параметры (максимально - десять), представления которых нужно подставить в строку.
Чтобы указать конкретное место в шаблоне, в которое нужно выполнить подстановку, нужно использовать маркеры вида %1, . %10. Количество маркеров, задействованных в шаблоне, и количество параметров, содержащих значения, должны совпадать.
Например, результатом выполнения такого оператора:
Ошибка в данных в строке 2 (требуется тип Дата)
Функция работы со строками СтрСравнить()
Эта функция сравнивает две строки без учёта регистра. Например, так:
Это же действие вы могли выполнить и раньше с помощью объекта СравнениеЗначений:
Однако использование новой функции выглядит более простым. А кроме этого функция, в отличие от объекта СравнениеЗначений, работает и в тонком клиенте, и в веб-клиенте.
Функции работы со строками СтрНачинаетсяС(), СтрЗаканчиваетсяНа()
Эти функции определяют, начинается ли строка с указанной подстроки, заканчивается ли строка указанной подстрокой. Алгоритм этих функций несложно реализовать на встроенном языке, но их наличие позволяет писать более чистый и понимаемый код. И работают они быстрее.
Например, их удобно использовать в операторе Если:
Функции работы со строками СтрРазделить(), СтрСоединить()
Эти функции разделяют строку на части по указанному разделителю. Или наоборот, соединяют несколько строк в одну, вставляя между ними выбранный разделитель. Они удобны для создания или анализа логов, технологического журнала. Например, запись технологического журнала вы можете легко разобрать на части, пригодные для дальнейшего анализа:
Функция работы со строками СтрНайти()
Вместо старой функции Найти() мы реализовали новую функцию, которая имеет дополнительные возможности:
- Поиск в разных направлениях (с начала, с конца);
- Поиск с указанной позиции;
- Поиск вхождения с указанным номером (второе, третье и т.д.).
Фактически она дублирует возможности старой функции. Так сделано для того, чтобы сохранить совместимость с модулями, скомпилированными в старых версиях. Старую функцию Найти() рекомендуется больше не использовать.
Ниже приведён пример, использующий новые возможности поиска. Поиск в обратном направлении удобен тогда, когда вам нужен последний фрагмент формализованной строки, например, полное имя файла в URL. А поиск с указанной позиции помогает в тех случаях, когда нужно искать в известном фрагменте, а не во всей строке.
Читайте также: