ПотокВПамяти.ТекущаяПозиция

Методы · CurrentPosition

Возвращает текущую позицию в потоке.

Синтаксис

ТекущаяПозиция()
Полное описание, параметры и ограничения

ПотокВПамяти.ТекущаяПозиция (MemoryStream.CurrentPosition)

ПотокВПамяти (MemoryStream)

ТекущаяПозиция (CurrentPosition)

Доступен, начиная с версии 8.3.9.

Синтаксис:
ТекущаяПозиция()
Возвращаемое значение:
Тип: Число.

Описание:

Возвращает текущую позицию в потоке.

Доступность:

Тонкий клиент, веб-клиент, мобильный клиент, сервер, толстый клиент, внешнее соединение, мобильное приложение (клиент), мобильное приложение (сервер), мобильный автономный сервер, интеграция.

Использование в версии:

Доступен, начиная с версии 8.3.9.

Методическая информация

Практические примеры

Отличить поток только для чтения от независимой копии

Читающий поток разделяет данные и текущую позицию с исходным: запрет записи не создаёт неизменяемый снимок.

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

Модуль пустой управляемой формы учебной внешней обработки; тонкий или толстый клиент Windows. Вставьте весь модуль. Это не серверный код.

Подготовка

  1. Создайте учебную внешнюю обработку с пустой управляемой основной формой. Создайте команду УчебныйПример и кнопку этой команды.

  2. В свойстве команды Действие выберите процедуру УчебныйПример. Вставьте полный приведённый модуль формы.

  3. Откройте EPF в тонком или толстом клиенте Windows и нажмите кнопку. Не переносите Ждать и Асинх в серверный общий модуль.

  4. Пример работает только со своими данными в памяти; записи в базу, файлы и сеть нет.

  5. Эти методы проверяются по установленной справке 8.5.1.1343, но фактический запуск в 1С здесь не подтверждён.

&НаКлиенте
Процедура УчебныйПример(Команда)
    Источник = Неопределено;
    ТолькоЧтение = Неопределено;
    ОшибкаОперации = "";
    Попытка
        Источник = Новый ПотокВПамяти;
        ИсходныйБуфер = Новый БуферДвоичныхДанных(5);
        Для ИндексБайта = 0 По 4 Цикл
            ИсходныйБуфер.Установить(ИндексБайта, (ИндексБайта + 1) * 10);
        КонецЦикла;
        Источник.Записать(ИсходныйБуфер, 0, 3);
        Источник.Перейти(0, ПозицияВПотоке.Начало);
        ТолькоЧтение = Источник.ПолучитьПотокТолькоДляЧтения();
        Сообщить(Не ТолькоЧтение.ДоступнаЗапись);
        БуферЧтения = Новый БуферДвоичныхДанных(3);
        Сообщить(ТолькоЧтение.Прочитать(БуферЧтения, 0, 1) = 1);
        Сообщить(Источник.ТекущаяПозиция() = 1);
        Изменение = Новый БуферДвоичныхДанных(1);
        Изменение.Установить(0, 42);
        Источник.Записать(Изменение, 0, 1);
        Сообщить(ТолькоЧтение.ТекущаяПозиция() = 2);
        ТолькоЧтение.Перейти(0, ПозицияВПотоке.Начало);
        Сообщить(Источник.ТекущаяПозиция() = 0);
        Сообщить(ТолькоЧтение.Прочитать(БуферЧтения, 0, 3) = 3);
        Сообщить(БуферЧтения.Получить(0) = 10);
        Сообщить(БуферЧтения.Получить(1) = 42);
        Сообщить(БуферЧтения.Получить(2) = 30);
    Исключение
        ОшибкаОперации = ОписаниеОшибки();
    КонецПопытки;
    ОшибкиЗакрытия = ЗакрытьСобственныеПотоки(ТолькоЧтение, Источник);
    Если Не ПустаяСтрока(ОшибкаОперации) Или Не ПустаяСтрока(ОшибкиЗакрытия) Тогда
        ВызватьИсключение ОшибкаОперации + " " + ОшибкиЗакрытия;
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Функция ЗакрытьСобственныеПотоки(Первый, Второй)
    Ошибки = "";
    Если Первый <> Неопределено Тогда
        Попытка
            Первый.Закрыть();
        Исключение
            Ошибки = "Первый поток не закрыт: " + ОписаниеОшибки();
        КонецПопытки;
    КонецЕсли;
    Если Второй <> Неопределено Тогда
        Попытка
            Второй.Закрыть();
        Исключение
            Ошибки = Ошибки + " Второй поток не закрыт: " + ОписаниеОшибки();
        КонецПопытки;
    КонецЕсли;
    Возврат Ошибки;
КонецФункции

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

  1. Создаём собственный поток 10/20/30 и устанавливаем позицию 0. ПолучитьПотокТолькоДляЧтения возвращает обёртку типа Поток, не отдельный ПотокВПамяти с копией байтов.

  2. После чтения одного байта через обёртку текущая позиция исходного потока тоже 1.

  3. Через исходный записывающий поток заменяем второй байт на 42. Текущая позиция обёртки становится 2, потому что позиция общая.

  4. Переход обёртки к началу меняет позицию исходного. Чтение снова получает 10/42/30, то есть видит изменения общего содержимого.

  5. После опыта больше не используем ни один поток; отдельно пытаемся закрыть обе принадлежащие примеру ссылки и сообщаем ошибки закрытия.

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

  1. Девять сравнений дают Истина; фактически прочитан пакет 10/42/30.

  2. Не было попытки записи через поток только для чтения и не было изменения внешних данных.

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

На конкретных байтах показано общее содержимое и общая позиция читающей обёртки.

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

  1. Только чтение защищает этот интерфейс записи, а не исходный поток от другого владельца.

  2. Для независимого снимка нужно отдельно копировать данные; данный метод такого обещания не даёт.

  3. Не используйте потоки после завершения очистки и не выводите из этого примера неподтверждённые гарантии многопоточности.

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

Записать байты в поток, прочитать часть и скопировать остаток

Поток хранит текущую позицию. Начальная ёмкость не означает заполненный размер; после записи чтение начинается с конца, пока позиция не изменена.

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

Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.

Подготовка

  1. Выполняйте на сервере; все потоки в памяти, файлов нет.

  2. Исходные четыре байта: 1, 2, 3, 4; ёмкость первого потока 64 — резерв памяти, не число данных.

Буфер = Новый БуферДвоичныхДанных(4);
Для Номер = 0 По 3 Цикл
    Буфер.Установить(Номер, Номер + 1);
КонецЦикла;
Поток = Новый ПотокВПамяти(64);
Копия = Новый ПотокВПамяти;
Попытка
    Сообщить(Поток.Размер());
    Сообщить(Поток.ДоступнаЗапись);
    Сообщить(Поток.ДоступноЧтение);
    Сообщить(Поток.ДоступноИзменениеПозиции);
    Поток.Записать(Буфер, 0, 4);
    Поток.СброситьБуферы();
    Сообщить(Поток.ТекущаяПозиция());
    Поток.Перейти(0, ПозицияВПотоке.Начало);
    Прочитанное = Новый БуферДвоичныхДанных(2);
    Прочитано = Поток.Прочитать(Прочитанное, 0, 2);
    Сообщить(Прочитано);
    Сообщить(Прочитанное.Получить(0));
    Поток.КопироватьВ(Копия, 2);
    Сообщить(Копия.Размер());
    ДанныеКопии = Копия.ЗакрытьИПолучитьДвоичныеДанные();
    Копия = Неопределено;
    Сообщить(ПолучитьHexСтрокуИзДвоичныхДанных(ДанныеКопии));
    Поток.УстановитьРазмер(3);
    Данные = Поток.ЗакрытьИПолучитьДвоичныеДанные();
    Поток = Неопределено;
Исключение
    Если Копия <> Неопределено Тогда
        Копия.Закрыть();
    КонецЕсли;
    Если Поток <> Неопределено Тогда
        Поток.Закрыть();
    КонецЕсли;
    ВызватьИсключение;
КонецПопытки;
Сообщить(ПолучитьHexСтрокуИзДвоичныхДанных(Данные));
Основа = ПолучитьБуферДвоичныхДанныхИзДвоичныхДанных(Данные);
ПотокИзБуфера = Новый ПотокВПамяти(Основа);
Сообщить(ПотокИзБуфера.Размер());
ПотокИзБуфера.Закрыть();

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

  1. Создаём два потока и проверяем размер пустого потока: 0.

  2. После записи позиция 4; Перейти перемещает её к началу для чтения.

  3. Прочитать возвращает фактическое число байтов. КопироватьВ начинает с текущей позиции, поэтому копирует только 3 и 4.

  4. УстановитьРазмер сокращает первый поток до трёх байтов; ЗакрытьИПолучитьДвоичныеДанные выдаёт содержимое и закрывает поток.

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

  1. Прочитано 2 байта, первый равен 1; содержимое копии в Hex — 0304.

  2. После сокращения исходные данные в Hex — 010203; поток, созданный на их буфере, имеет размер 3.

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

Частичное чтение, копирование остатка и сокращение потока выполнены без файлов.

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

  1. После ЗакрытьИПолучитьДвоичныеДанные поток больше не используйте.

  2. Прочитать может вернуть меньше запрошенного количества, особенно у сетевых потоков: всегда проверяйте возвращённое число.

  3. НачальнаяЁмкость — объём резервирования, УстановитьРазмер — изменение фактических данных; это разные операции.

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

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

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

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

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