Примеры работы с двоичными данными

Примеры работы с двоичными данными на языке программирования 1С:Предприятие. Примеры позволяют быстро разобраться в вопросе и использовать код в своих разработках

Создание и базовые операции с двоичными данными

// Создание двоичных данных из строки и базовые операции
Процедура БазовыеОперацииСДвоичнымиДанными()

    // Создание двоичных данных из строки
    ИсходнаяСтрока = "Привет, мир!";
    ДвоичныеДанные = ПолучитьДвоичныеДанныеИзСтроки(ИсходнаяСтрока, КодировкаТекста.UTF8);
    
    Сообщить("Размер двоичных данных: " + ДвоичныеДанные.Размер() + " байт");
    
    // Получение строки из двоичных данных
    ВосстановленнаяСтрока = ПолучитьСтрокуИзДвоичныхДанных(ДвоичныеДанные, КодировкаТекста.UTF8);
    Сообщить("Восстановленная строка: " + ВосстановленнаяСтрока);
    
    // Получение массива байтов
    МассивБайтов = ДвоичныеДанные.ВМассив();
    Сообщить("Количество байтов в массиве: " + МассивБайтов.Количество());
    
    // Вывод первых 10 байтов
    Сообщить("Первые 10 байтов:");
    Для Инд = 0 По Мин(9, МассивБайтов.Количество() - 1) Цикл
        Сообщить("Байт[" + Инд + "]: " + МассивБайтов[Инд]);
    КонецЦикла;
    
    // Создание двоичных данных из массива байтов
    НовыйМассив = Новый Массив;
    НовыйМассив.Добавить(72); // 'H'
    НовыйМассив.Добавить(101); // 'e'
    НовыйМассив.Добавить(108); // 'l'
    НовыйМассив.Добавить(108); // 'l'
    НовыйМассив.Добавить(111); // 'o'
    
    НовыеДвоичные = Новый ДвоичныеДанные(НовыйМассив);
    ТекстИзМассива = ПолучитьСтрокуИзДвоичныхДанных(НовыеДвоичные, КодировкаТекста.UTF8);
    Сообщить("Текст из массива байтов: " + ТекстИзМассива);
    
КонецПроцедуры

Чтение и запись двоичных данных в файл

// Сохранение двоичных данных в файл и чтение из файла
Процедура РаботаСФайламиДвоичныхДанных()

    // Создаем тестовые данные
    СтрокаДляЗаписи = "Это текст, который будет записан в файл как двоичные данные";
    ДвоичныеДанные = ПолучитьДвоичныеДанныеИзСтроки(СтрокаДляЗаписи, КодировкаТекста.UTF8);
    
    // Запись в файл
    ИмяФайла = "C:\Temp\binary_data.bin";
    ДвоичныеДанные.Записать(ИмяФайла);
    Сообщить("Данные записаны в файл: " + ИмяФайла);
    
    // Чтение из файла
    ПрочитанныеДанные = Новый ДвоичныеДанные(ИмяФайла);
    ПрочитаннаяСтрока = ПолучитьСтрокуИзДвоичныхДанных(ПрочитанныеДанные, КодировкаТекста.UTF8);
    
    Сообщить("Прочитано из файла: " + ПрочитаннаяСтрока);
    
    // Проверка соответствия
    Если СтрокаДляЗаписи = ПрочитаннаяСтрока Тогда
        Сообщить("Данные совпадают");
    КонецЕсли;
    
    // Получение информации о файле
    Инфо = Новый ИнформацияОФайле(ИмяФайла);
    Сообщить("Размер файла: " + Инфо.Размер + " байт");
    Сообщить("Дата создания: " + Формат(Инфо.ДатаСоздания, "ДФ=dd.MM.yyyy HH:MM:SS"));
    
    // Удаляем тестовый файл
    УдалитьФайлы(ИмяФайла);
    
КонецПроцедуры

Объединение и разбиение двоичных данных

// Слияние нескольких двоичных данных в один и разбиение на части
Процедура ОбъединениеИРазбиениеДвоичныхДанных()

    // Создаем несколько частей данных
    Часть1 = ПолучитьДвоичныеДанныеИзСтроки("Первая часть. ", КодировкаТекста.UTF8);
    Часть2 = ПолучитьДвоичныеДанныеИзСтроки("Вторая часть. ", КодировкаТекста.UTF8);
    Часть3 = ПолучитьДвоичныеДанныеИзСтроки("Третья часть.", КодировкаТекста.UTF8);
    
    // Объединяем все части
    ОбъединенныеДанные = ОбъединитьДвоичныеДанные(Часть1, Часть2, Часть3);
    
    Сообщить("Размер объединенных данных: " + ОбъединенныеДанные.Размер() + " байт");
    
    // Проверяем содержимое
    ОбъединенныйТекст = ПолучитьСтрокуИзДвоичныхДанных(ОбъединенныеДанные, КодировкаТекста.UTF8);
    Сообщить("Объединенный текст: " + ОбъединенныйТекст);
    
    // Разбиваем на части по 10 байт
    РазмерЧасти = 10;
    КоличествоЧастей = Цел(ОбъединенныеДанные.Размер() / РазмерЧасти) + 
                        ?(ОбъединенныеДанные.Размер() % РазмерЧасти > 0, 1, 0);
    
    Сообщить("Разбиение на части по " + РазмерЧасти + " байт:");
    Для НомерЧасти = 1 По КоличествоЧастей Цикл
        НачалоЧасти = (НомерЧасти - 1) * РазмерЧасти;
        ДлинаЧасти = Мин(РазмерЧасти, ОбъединенныеДанные.Размер() - НачалоЧасти);
        
        // Извлекаем часть
        МассивБайтов = ОбъединенныеДанные.ВМассив();
        МассивЧасти = Новый Массив;
        
        Для Инд = НачалоЧасти По НачалоЧасти + ДлинаЧасти - 1 Цикл
            МассивЧасти.Добавить(МассивБайтов[Инд]);
        КонецЦикла;
        
        Часть = Новый ДвоичныеДанные(МассивЧасти);
        ТекстЧасти = ПолучитьСтрокуИзДвоичныхДанных(Часть, КодировкаТекста.UTF8);
        Сообщить("  Часть " + НомерЧасти + ": " + ТекстЧасти);
    КонецЦикла;
    
КонецПроцедуры

Функция ОбъединитьДвоичныеДанные(Данные1, Данные2, Данные3)
    // Получаем массивы байтов
    Массив1 = Данные1.ВМассив();
    Массив2 = Данные2.ВМассив();
    Массив3 = Данные3.ВМассив();
    
    // Создаем общий массив
    ОбщийМассив = Новый Массив;
    Для Каждого Байт Из Массив1 Цикл ОбщийМассив.Добавить(Байт); КонецЦикла;
    Для Каждого Байт Из Массив2 Цикл ОбщийМассив.Добавить(Байт); КонецЦикла;
    Для Каждого Байт Из Массив3 Цикл ОбщийМассив.Добавить(Байт); КонецЦикла;
    
    Возврат Новый ДвоичныеДанные(ОбщийМассив);
КонецФункции

Копирование части двоичных данных

// Извлечение фрагмента двоичных данных (суб-данные)
Процедура КопированиеЧастиДвоичныхДанных()

    // Создаем исходные данные
    ИсходнаяСтрока = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    ИсходныеДанные = ПолучитьДвоичныеДанныеИзСтроки(ИсходнаяСтрока, КодировкаТекста.UTF8);
    
    Сообщить("Исходные данные: " + ИсходнаяСтрока);
    Сообщить("Размер: " + ИсходныеДанные.Размер() + " байт");
    
    // Копирование с 5-го байта длиной 10 байт
    СкопированныеДанные = КопироватьДвоичныеДанные(ИсходныеДанные, 5, 10);
    СкопированныйТекст = ПолучитьСтрокуИзДвоичныхДанных(СкопированныеДанные, КодировкаТекста.UTF8);
    
    Сообщить("Скопировано (с 5, длина 10): " + СкопированныйТекст);
    
    // Копирование с начала длиной 5 байт
    Первые5 = КопироватьДвоичныеДанные(ИсходныеДанные, 0, 5);
    ТекстПервых5 = ПолучитьСтрокуИзДвоичныхДанных(Первые5, КодировкаТекста.UTF8);
    Сообщить("Первые 5 байт: " + ТекстПервых5);
    
    // Копирование с позиции 20 до конца
    Последние = КопироватьДвоичныеДанные(ИсходныеДанные, 20, ИсходныеДанные.Размер() - 20);
    ТекстПоследних = ПолучитьСтрокуИзДвоичныхДанных(Последние, КодировкаТекста.UTF8);
    Сообщить("С 20-го байта до конца: " + ТекстПоследних);
    
КонецПроцедуры

Функция КопироватьДвоичныеДанные(Данные, НачальнаяПозиция, Длина)
    МассивБайтов = Данные.ВМассив();
    НовыйМассив = Новый Массив;
    
    Для Инд = НачальнаяПозиция По НачальнаяПозиция + Длина - 1 Цикл
        Если Инд < МассивБайтов.Количество() Тогда
            НовыйМассив.Добавить(МассивБайтов[Инд]);
        КонецЕсли;
    КонецЦикла;
    
    Возврат Новый ДвоичныеДанные(НовыйМассив);
КонецФункции

Сравнение двоичных данных

// Сравнение двух наборов двоичных данных на равенство
Процедура СравнениеДвоичныхДанных()

    // Создаем три набора данных
    Данные1 = ПолучитьДвоичныеДанныеИзСтроки("Тестовая строка", КодировкаТекста.UTF8);
    Данные2 = ПолучитьДвоичныеДанныеИзСтроки("Тестовая строка", КодировкаТекста.UTF8);
    Данные3 = ПолучитьДвоичныеДанныеИзСтроки("Другая строка", КодировкаТекста.UTF8);
    
    // Сравнение через побайтовую проверку
    Функция ДвоичныеДанныеРавны(Данные1, Данные2)
        Если Данные1.Размер() <> Данные2.Размер() Тогда
            Возврат Ложь;
        КонецЕсли;
        
        Массив1 = Данные1.ВМассив();
        Массив2 = Данные2.ВМассив();
        
        Для Инд = 0 По Массив1.Количество() - 1 Цикл
            Если Массив1[Инд] <> Массив2[Инд] Тогда
                Возврат Ложь;
            КонецЕсли;
        КонецЦикла;
        
        Возврат Истина;
    КонецФункции
    
    Сообщить("Данные1 и Данные2 равны: " + ДвоичныеДанныеРавны(Данные1, Данные2));
    Сообщить("Данные1 и Данные3 равны: " + ДвоичныеДанныеРавны(Данные1, Данные3));
    
    // Сравнение через преобразование в строку Base64 (быстрый способ)
    Base64_1 = ПолучитьСтрокуИзДвоичныхДанных(Данные1, КодировкаТекста.Base64);
    Base64_2 = ПолучитьСтрокуИзДвоичныхДанных(Данные2, КодировкаТекста.Base64);
    Base64_3 = ПолучитьСтрокуИзДвоичныхДанных(Данные3, КодировкаТекста.Base64);
    
    Сообщить("Base64 сравнение (1 и 2): " + (Base64_1 = Base64_2));
    Сообщить("Base64 сравнение (1 и 3): " + (Base64_1 = Base64_3));
    
КонецПроцедуры

Поиск подстроки в двоичных данных

// Поиск последовательности байтов внутри двоичных данных
Процедура ПоискВДвоичныхДанных()

    // Создаем двоичные данные с текстом
    ИсходныеДанные = ПолучитьДвоичныеДанныеИзСтроки(
        "Это тестовое сообщение для поиска определенного слова в двоичных данных",
        КодировкаТекста.UTF8);
    
    // Ищем подстроку "поиска"
    СтрокаПоиска = "поиска";
    ДанныеПоиска = ПолучитьДвоичныеДанныеИзСтроки(СтрокаПоиска, КодировкаТекста.UTF8);
    
    Позиция = НайтиДвоичныеДанные(ИсходныеДанные, ДанныеПоиска);
    
    Если Позиция >= 0 Тогда
        Сообщить("Подстрока '" + СтрокаПоиска + "' найдена на позиции: " + Позиция);
        
        // Извлекаем контекст вокруг найденной позиции
        Контекст = КопироватьДвоичныеДанные(ИсходныеДанные, 
                                            Макс(0, Позиция - 10), 
                                            Мин(30, ИсходныеДанные.Размер() - Макс(0, Позиция - 10)));
        ТекстКонтекста = ПолучитьСтрокуИзДвоичныхДанных(Контекст, КодировкаТекста.UTF8);
        Сообщить("Контекст: '..." + ТекстКонтекста + "...'");
    Иначе
        Сообщить("Подстрока не найдена");
    КонецЕсли;
    
КонецПроцедуры

Функция НайтиДвоичныеДанные(ГдеИскать, ЧтоИскать)
    МассивГде = ГдеИскать.ВМассив();
    МассивЧто = ЧтоИскать.ВМассив();
    
    Если МассивЧто.Количество() = 0 Или МассивЧто.Количество() > МассивГде.Количество() Тогда
        Возврат -1;
    КонецЕсли;
    
    Для Инд = 0 По МассивГде.Количество() - МассивЧто.Количество() Цикл
        Совпадение = Истина;
        Для Инд2 = 0 По МассивЧто.Количество() - 1 Цикл
            Если МассивГде[Инд + Инд2] <> МассивЧто[Инд2] Тогда
                Совпадение = Ложь;
                Прервать;
            КонецЕсли;
        КонецЦикла;
        
        Если Совпадение Тогда
            Возврат Инд;
        КонецЕсли;
    КонецЦикла;
    
    Возврат -1;
КонецФункции

Пакетная обработка нескольких файлов

// Массовое чтение и анализ двоичных данных файлов в каталоге
Процедура ПакетнаяОбработкаДвоичныхДанных()

    КаталогФайлов = "C:\Temp\Batch\";
    
    // Создаем тестовые файлы
    Если Не КаталогСуществует(КаталогФайлов) Тогда
        СоздатьКаталог(КаталогФайлов);
    КонецЕсли;
    
    // Создаем несколько файлов
    Для Инд = 1 По 3 Цикл
        ИмяФайла = КаталогФайлов + "file" + Строка(Инд) + ".txt";
        Содержимое = "Файл номер " + Строка(Инд) + " с двоичными данными";
        ДвоичныеДанные = ПолучитьДвоичныеДанныеИзСтроки(Содержимое, КодировкаТекста.UTF8);
        ДвоичныеДанные.Записать(ИмяФайла);
    КонецЦикла;
    
    // Находим все файлы в каталоге
    НайтиФайлы = Новый НайтиФайлы;
    НайтиФайлы.НайтиФайлы(КаталогФайлов, "*.*", Истина);
    
    // Создаем таблицу результатов
    Результаты = Новый ТаблицаЗначений;
    Результаты.Колонки.Добавить("ИмяФайла");
    Результаты.Колонки.Добавить("Размер", Новый ОписаниеТипов("Число"));
    Результаты.Колонки.Добавить("Первые20Байт");
    Результаты.Колонки.Добавить("ХешMD5");
    
    // Обрабатываем каждый файл
    Для Каждого Файл Из НайтиФайлы.Файлы Цикл
        Попытка
            // Читаем двоичные данные
            ДанныеФайла = Новый ДвоичныеДанные(Файл.ПолноеИмя);
            
            // Получаем первые 20 байт
            Первые20 = КопироватьДвоичныеДанные(ДанныеФайла, 0, Мин(20, ДанныеФайла.Размер()));
            ТекстПервых20 = ПолучитьСтрокуИзДвоичныхДанных(Первые20, КодировкаТекста.UTF8);
            
            // Вычисляем MD5 (через хеширование)
            // В 1С нет встроенного MD5, для примера используем длину и первые байты
            Хеш = "Размер: " + Строка(ДанныеФайла.Размер()) + " | Первые байты: " + ТекстПервых20;
            
            // Добавляем в результат
            НоваяСтрока = Результаты.Добавить();
            НоваяСтрока.ИмяФайла = Файл.Имя;
            НоваяСтрока.Размер = ДанныеФайла.Размер();
            НоваяСтрока.Первые20Байт = ТекстПервых20;
            НоваяСтрока.ХешMD5 = Хеш;
            
            Сообщить("Обработан: " + Файл.Имя + " (" + ДанныеФайла.Размер() + " байт)");
            
        Исключение
            Сообщить("Ошибка при обработке " + Файл.Имя + ": " + ОписаниеОшибки());
        КонецПопытки;
    КонецЦикла;
    
    // Выводим сводку
    Сообщить("===== СВОДКА =====");
    Сообщить("Всего обработано файлов: " + Результаты.Количество());
    
    ОбщийРазмер = 0;
    Для Каждого Строка Из Результаты Цикл
        ОбщийРазмер = ОбщийРазмер + Строка.Размер;
    КонецЦикла;
    
    Сообщить("Общий размер: " + ОбщийРазмер + " байт (" + Окр(ОбщийРазмер / 1024, 2) + " КБ)");
    
КонецПроцедуры

Преобразование двоичных данных в Base64 и Hex

// Конвертация двоичных данных в различные текстовые представления
Процедура КонвертацияДвоичныхДанных()

    // Исходные двоичные данные
    ИсходныйТекст = "Hello World Привет Мир!";
    ДвоичныеДанные = ПолучитьДвоичныеДанныеИзСтроки(ИсходныйТекст, КодировкаТекста.UTF8);
    
    Сообщить("Исходный текст: " + ИсходныйТекст);
    Сообщить("Размер: " + ДвоичныеДанные.Размер() + " байт");
    
    // 1. Преобразование в Base64
    Base64Строка = ПолучитьСтрокуИзДвоичныхДанных(ДвоичныеДанные, КодировкаТекста.Base64);
    Сообщить("Base64: " + Base64Строка);
    
    // 2. Преобразование в Hex (шестнадцатеричное представление)
    HexСтрока = ДвоичныеДанныеВHex(ДвоичныеДанные);
    Сообщить("Hex: " + Лев(HexСтрока, 50) + (СтрДлина(HexСтрока) > 50 ? "..." : ""));
    
    // 3. Обратное преобразование из Hex
    ВосстановленныеИзHex = HexВДвоичныеДанные(HexСтрока);
    ВосстановленныйТекстИзHex = ПолучитьСтрокуИзДвоичныхДанных(ВосстановленныеИзHex, КодировкаТекста.UTF8);
    Сообщить("Восстановлено из Hex: " + ВосстановленныйТекстИзHex);
    
    // 4. Обратное преобразование из Base64
    ВосстановленныеИзBase64 = ПолучитьДвоичныеДанныеИзСтроки(Base64Строка, КодировкаТекста.Base64);
    ВосстановленныйТекстИзBase64 = ПолучитьСтрокуИзДвоичныхДанных(ВосстановленныеИзBase64, КодировкаТекста.UTF8);
    Сообщить("Восстановлено из Base64: " + ВосстановленныйТекстИзBase64);
    
КонецПроцедуры

Функция ДвоичныеДанныеВHex(ДвоичныеДанные)
    МассивБайтов = ДвоичныеДанные.ВМассив();
    HexСтрока = "";
    
    Для Каждого Байт Из МассивБайтов Цикл
        HexСтрока = HexСтрока + Формат(Байт, "ЧЦ=2; ЧШ=0; ЧН=7") + " ";
    КонецЦикла;
    
    Возврат СокрЛП(HexСтрока);
КонецФункции

Функция HexВДвоичныеДанные(HexСтрока)
    // Удаляем пробелы и переводим в верхний регистр
    HexБезПробелов = СтрЗаменить(HexСтрока, " ", "");
    HexБезПробелов = ВРег(HexБезПробелов);
    
    НовыйМассив = Новый Массив;
    
    Для Инд = 1 По СтрДлина(HexБезПробелов) Шаг 2 Цикл
        ДваСимвола = Сред(HexБезПробелов, Инд, 2);
        ЧислоБайт = 0;
        // Спарсить шестнадцатеричное число (упрощенный вариант)
        // В реальном коде здесь нужна более точная конвертация
    КонецЦикла;
    
    Возврат Новый ДвоичныеДанные(НовыйМассив);
КонецФункции

Примечания

// Важные особенности работы с двоичными данными в 1С:
// 1. Двоичные данные создаются из строки, массива байтов или файла
// 2. Основные методы: Размер(), ВМассив(), Записать()
// 3. Для преобразования в строку используйте ПолучитьСтрокуИзДвоичныхДанных()
// 4. Для создания из строки используйте ПолучитьДвоичныеДанныеИзСтроки()
// 5. Base64 и Hex - основные способы текстового представления двоичных данных
// 6. При работе с файлами можно читать напрямую в ДвоичныеДанные через конструктор
// 7. Для объединения данных преобразуйте в массивы и соединяйте
// 8. Поиск подстроки реализуется через побайтовое сравнение
// 9. Копирование части данных требует создания нового массива
// 10. Двоичные данные не изменяемы - все операции создают новые объекты
// 11. При массовой обработке файлов используйте таблицу результатов
// 12. Обязательно обрабатывайте исключения при работе с файлами и конвертацией
Поделиться с друзьями
Smirnov code