Прочитать ABC123 частями по четыре байта

Учебные задачи

Последняя часть содержит два байта, хотя буфер рассчитан на четыре. Собираем только фактически прочитанные байты и обнаруживаем конец по нулю.

Где и как запускать

Серверная процедура отдельной учебной базы; локальный временный файл сервера.

Подготовка

  1. Каждый фрагмент запускайте отдельно в серверной процедуре своей учебной базы. Файл создаётся во временном каталоге сервера, не на компьютере клиента.

  2. Пример получает новое временное имя и использует СоздатьНовый, не Создать. Чужой существующий файл никогда не открывается для перезаписи.

  3. После завершения/ошибки закрываются только созданные потоки и удаляется только точное собственное имя. Это не резервная копия и не операция над вашими XML.

ИмяФайла = ПолучитьИмяВременногоФайла("bin");
УчебныйФайл = Новый Файл(ИмяФайла);
Если УчебныйФайл.Существует() Тогда
    ВызватьИсключение "Временное имя уже занято: чужой файл не открываем";
КонецЕсли;
Поток = Неопределено;
Вид = Неопределено;
Копия = Неопределено;
СозданСвойФайл = Ложь;
Попытка
    Поток = Новый ФайловыйПоток(ИмяФайла, РежимОткрытияФайла.СоздатьНовый, ДоступКФайлу.ЧтениеИЗапись);
    СозданСвойФайл = Истина;
    Буфер = ПолучитьБуферДвоичныхДанныхИзСтроки("ABC123", КодировкаТекста.UTF8, Ложь);
    Поток.Записать(Буфер, 0, Буфер.Размер);
    Поток.Перейти(0, ПозицияВПотоке.Начало);
    Часть = Новый БуферДвоичныхДанных(4);
    Собранный = Новый БуферДвоичныхДанных(6);
    Всего = 0;
    Количество = Поток.Прочитать(Часть, 0, Часть.Размер);
    Пока Количество > 0 Цикл
        Если Всего + Количество > Собранный.Размер Тогда
            ВызватьИсключение "Учебный поток неожиданно больше шести байтов";
        КонецЕсли;
        Для Индекс = 0 По Количество - 1 Цикл
            Собранный.Установить(Всего + Индекс, Часть.Получить(Индекс));
        КонецЦикла;
        Сообщить(Количество);
        Всего = Всего + Количество;
        Количество = Поток.Прочитать(Часть, 0, Часть.Размер);
    КонецЦикла;
    Сообщить(Всего = 6);
    Сообщить(Количество = 0);
    Сообщить(ПолучитьСтрокуИзБуфераДвоичныхДанных(Собранный, КодировкаТекста.UTF8) = "ABC123");
Исключение
    Если Вид <> Неопределено Тогда
        Вид.Закрыть();
    КонецЕсли;
    Если Копия <> Неопределено Тогда
        Копия.Закрыть();
    КонецЕсли;
    Если Поток <> Неопределено Тогда
        Поток.Закрыть();
    КонецЕсли;
    Если СозданСвойФайл И УчебныйФайл.Существует() Тогда
        УдалитьФайлы(ИмяФайла);
    КонецЕсли;
    ВызватьИсключение;
КонецПопытки;
Если Вид <> Неопределено Тогда
    Вид.Закрыть();
КонецЕсли;
Если Копия <> Неопределено Тогда
    Копия.Закрыть();
КонецЕсли;
Если Поток <> Неопределено Тогда
    Поток.Закрыть();
КонецЕсли;
Если СозданСвойФайл Тогда
    УдалитьФайлы(ИмяФайла);
КонецЕсли;
Сообщить(Не УчебныйФайл.Существует());

Разбор по шагам

  1. После записи возвращаем позицию в начало и создаём отдельный четырёхбайтный рабочий буфер.

  2. В цикле используем фактический результат Прочитать, не ёмкость Часть.Размер.

  3. Перед переносом проверяем границы шестибайтного результата; конец наступает при Количество=0.

  4. Декодируем только полностью собранные шесть ASCII-байтов, а не отдельные фрагменты текста.

Как проверить результат

  1. Цикл выводит 4 и 2; третье чтение 0 завершает цикл.

  2. Три сравнения Истина: шесть байтов, конец по нулю и исходная строка ABC123.

  3. Последнее сообщение Истина: точный собственный временный файл удалён после закрытия ресурсов.

Ожидаемый результат

Отработано чтение с неполной последней порцией без повторного использования лишних байтов.

На что обратить внимание

  1. Для большого/неизвестного файла не выделяйте весь размер без ограничений; здесь результат заранее ограничен шестью байтами.

  2. Кириллица UTF-8 может разделиться между порциями: не декодируйте каждую порцию независимо без обработки неполной последовательности.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.