Выполняет чтение заданного количества байтов в указанный буфер по указанному смещению. Текущая позиция смещается вперед на фактическое количество прочитанных байтов. Чтение из потока возможно только, если поток поддерживает чтение. В противном случае, будет вызвано исключение. При чтении размер целевого буфера не меняется, а его содержимое перезаписывается фактически прочитанными данными. Если в буфере недостаточно места для записи прочитанных данных, происходит ошибка переполнения.
Синтаксис
Прочитать(<Буфер>, <ПозицияВБуфере>, <Количество>)Полное описание, параметры и ограничения
ПотокВПамяти.Прочитать (MemoryStream.Read)
ПотокВПамяти (MemoryStream)
Прочитать (Read)
Доступен, начиная с версии 8.3.9.
Синтаксис:
Прочитать(<Буфер>, <ПозицияВБуфере>, <Количество>)
Параметры:
<Буфер> (обязательный)
Тип: БуферДвоичныхДанных.
Буфер, в который выполняется чтение.
<ПозицияВБуфере> (обязательный)
Тип: Число.
Позиция в целевом буфере, начиная с которой требуется записывать данные из потока.
<Количество> (обязательный)
Тип: Число.
Количество байт, которые требуется записать в целевой буфер.
Возвращаемое значение:
Тип: Число.
Фактически прочитанное количество байтов. Может быть меньше,указанного, если достигнут конец потока.
Описание:
Выполняет чтение заданного количества байтов в указанный буфер по указанному смещению. Текущая позиция смещается вперед на фактическое количество прочитанных байтов.
Чтение из потока возможно только, если поток поддерживает чтение. В противном случае, будет вызвано исключение.
При чтении размер целевого буфера не меняется, а его содержимое перезаписывается фактически прочитанными данными. Если в буфере недостаточно места для записи прочитанных данных, происходит ошибка переполнения.
Доступность:
Тонкий клиент, веб-клиент, мобильный клиент, сервер, толстый клиент, внешнее соединение, мобильное приложение (клиент), мобильное приложение (сервер), мобильный автономный сервер, интеграция.
См. также:
Поток, метод НачатьЧтение
Поток, метод ПрочитатьАсинх
Использование в версии:
Доступен, начиная с версии 8.3.9.
Описание изменено в версии 8.3.18.
Методическая информация
Практические примеры
Записать байты в поток, прочитать часть и скопировать остаток
Поток хранит текущую позицию. Начальная ёмкость не означает заполненный размер; после записи чтение начинается с конца, пока позиция не изменена.
Где и как запускать
Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.
Подготовка
Выполняйте на сервере; все потоки в памяти, файлов нет.
Исходные четыре байта: 1, 2, 3, 4; ёмкость первого потока 64 — резерв памяти, не число данных.
Буфер = Новый БуферДвоичныхДанных(4);
Для Номер = 0 По 3 Цикл
Буфер.Установить(Номер, Номер + 1);
КонецЦикла;
Поток = Новый ПотокВПамяти(64);
Копия = Новый ПотокВПамяти;
Попытка
Сообщить(Поток.Размер());
Сообщить(Поток.ДоступнаЗапись);
Сообщить(Поток.ДоступноЧтение);
Сообщить(Поток.ДоступноИзменениеПозиции);
Поток.Записать(Буфер, 0, 4);
Поток.СброситьБуферы();
Сообщить(Поток.ТекущаяПозиция());
Поток.Перейти(0, ПозицияВПотоке.Начало);
Прочитанное = Новый БуферДвоичныхДанных(2);
Прочитано = Поток.Прочитать(Прочитанное, 0, 2);
Сообщить(Прочитано);
Сообщить(Прочитанное.Получить(0));
Поток.КопироватьВ(Копия, 2);
Сообщить(Копия.Размер());
ДанныеКопии = Копия.ЗакрытьИПолучитьДвоичныеДанные();
Копия = Неопределено;
Сообщить(ПолучитьHexСтрокуИзДвоичныхДанных(ДанныеКопии));
Поток.УстановитьРазмер(3);
Данные = Поток.ЗакрытьИПолучитьДвоичныеДанные();
Поток = Неопределено;
Исключение
Если Копия <> Неопределено Тогда
Копия.Закрыть();
КонецЕсли;
Если Поток <> Неопределено Тогда
Поток.Закрыть();
КонецЕсли;
ВызватьИсключение;
КонецПопытки;
Сообщить(ПолучитьHexСтрокуИзДвоичныхДанных(Данные));
Основа = ПолучитьБуферДвоичныхДанныхИзДвоичныхДанных(Данные);
ПотокИзБуфера = Новый ПотокВПамяти(Основа);
Сообщить(ПотокИзБуфера.Размер());
ПотокИзБуфера.Закрыть();Разбор по шагам
Создаём два потока и проверяем размер пустого потока: 0.
После записи позиция 4; Перейти перемещает её к началу для чтения.
Прочитать возвращает фактическое число байтов. КопироватьВ начинает с текущей позиции, поэтому копирует только 3 и 4.
УстановитьРазмер сокращает первый поток до трёх байтов; ЗакрытьИПолучитьДвоичныеДанные выдаёт содержимое и закрывает поток.
Как проверить результат
Прочитано 2 байта, первый равен 1; содержимое копии в Hex — 0304.
После сокращения исходные данные в Hex — 010203; поток, созданный на их буфере, имеет размер 3.
Ожидаемый результат
Частичное чтение, копирование остатка и сокращение потока выполнены без файлов.
На что обратить внимание
После ЗакрытьИПолучитьДвоичныеДанные поток больше не используйте.
Прочитать может вернуть меньше запрошенного количества, особенно у сетевых потоков: всегда проверяйте возвращённое число.
НачальнаяЁмкость — объём резервирования, УстановитьРазмер — изменение фактических данных; это разные операции.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.
Удалить только собственное вложение с проверкой версии PDF
До записи удаления проверяем заголовок собственного PDF: метод требует версию не ниже 1.5. Другие документы и файлы не затрагиваются.
Где и как запускать
Серверная процедура отдельной учебной базы; собственный PDF и потоки в памяти.
Подготовка
Используйте отдельную учебную базу. Фрагмент без директив вставьте в тело серверной процедуры ВыполнитьПример() Экспорт общего модуля УчебныеЗадачи.
Все исходные байты создаются самим примером в памяти. Файлы, сеть, справочники и документы не нужны.
Запускайте задачи отдельно. После закрытия ЧтениеДанных/ЗаписьДанных не используйте этот экземпляр повторно.
Документ PDF строится из собственной ячейки Книга: 3 шт. Внешний PDF, установленный PDF-редактор, криптографический сертификат и реальные персональные данные не нужны.
Файловый путь нигде не используется. Для просмотра в PDF-программе сохраните только полученные собственные двоичные данные в отдельно выбранный новый учебный файл.
Вложения = Новый КоллекцияВложенийPDF;
ТекстJSON = "{""товар"":""Книга"",""количество"":3}";
БайтыJSON = ПолучитьДвоичныеДанныеИзСтроки(ТекстJSON, КодировкаТекста.UTF8, Ложь);
Вложения.Добавить("товар.json", БайтыJSON, "application/json", ТипСвязиВложенияPDF.Данные);
Чтение = Неопределено;
Запись = Неопределено;
ПотокЧтения = Неопределено;
ПотокPDF = Новый ПотокВПамяти;
Документ = Новый ТабличныйДокумент;
Документ.Область("A1").Текст = "Книга: 3 шт.";
Документ.Область("A1").ЦветТекста = Новый Цвет(30, 90, 180);
Попытка
Документ.Записать(ПотокPDF, ТипФайлаТабличногоДокумента.PDF, Вложения);
ПотокPDF.Перейти(0, ПозицияВПотоке.Начало);
Заголовок = Новый БуферДвоичныхДанных(8);
Если ПотокPDF.Прочитать(Заголовок, 0, 8) <> 8 Тогда
ВызватьИсключение "Недостаточно байтов для учебного заголовка PDF";
КонецЕсли;
СтрокаЗаголовка = ПолучитьСтрокуИзБуфераДвоичныхДанных(Заголовок, КодировкаТекста.UTF8);
Если СтрокаЗаголовка <> "%PDF-1.5" И СтрокаЗаголовка <> "%PDF-1.6" И СтрокаЗаголовка <> "%PDF-1.7" И СтрокаЗаголовка <> "%PDF-2.0" Тогда
ВызватьИсключение "Этот учебный PDF не прошёл явную проверку поддерживаемого заголовка: удаление не выполняется";
КонецЕсли;
ПотокPDF.Перейти(0, ПозицияВПотоке.Начало);
Запись = Новый ЗаписьPDF(ПотокPDF);
ИменаУдаления = Новый Массив;
ИменаУдаления.Добавить("товар.json");
Запись.ЗаписатьУдалениеВложений(ИменаУдаления);
Запись.Закрыть();
Запись = Неопределено;
БайтыPDF = ПотокPDF.ЗакрытьИПолучитьДвоичныеДанные();
ПотокPDF = Неопределено;
ПотокЧтения = БайтыPDF.ОткрытьПотокДляЧтения();
Чтение = Новый ЧтениеPDF(ПотокЧтения);
Прочитанные = Чтение.ПолучитьВложения();
Сообщить(Прочитанные.Количество() = 0);
Сообщить(Прочитанные.Найти("товар.json") = Неопределено);
Исключение
Если Чтение <> Неопределено Тогда
Чтение.Закрыть();
КонецЕсли;
Если Запись <> Неопределено Тогда
Запись.Закрыть();
КонецЕсли;
Если ПотокЧтения <> Неопределено Тогда
ПотокЧтения.Закрыть();
КонецЕсли;
Если ПотокPDF <> Неопределено Тогда
ПотокPDF.Закрыть();
КонецЕсли;
ВызватьИсключение;
КонецПопытки;
Если Чтение <> Неопределено Тогда
Чтение.Закрыть();
КонецЕсли;
Если Запись <> Неопределено Тогда
Запись.Закрыть();
КонецЕсли;
Если ПотокЧтения <> Неопределено Тогда
ПотокЧтения.Закрыть();
КонецЕсли;
Если ПотокPDF <> Неопределено Тогда
ПотокPDF.Закрыть();
КонецЕсли;Разбор по шагам
Исходный PDF принадлежит этому упражнению и содержит одно своё вложение.
Прочитать должен вернуть ровно восемь байтов. При неподдержанном заголовке явно останавливаем упражнение, не называем удаление успешным.
ЗаписатьУдалениеВложений получает массив имён, не коллекцию объектов ВложениеPDF.
После закрытия записи проверяем отсутствие имени независимым чтением. Байты удалённого вложения могут физически сохраняться внутри истории PDF.
Как проверить результат
Для поддержанного заголовка две проверки Истина; при неподдержанном — объяснимое исключение до изменения.
Удаление имени из списка вложений не следует считать безопасным уничтожением секретных байтов.
Ожидаемый результат
Удалено собственное вложение из перечня документа; предварительно проверено требование версии.
На что обратить внимание
Проверка восьми байтов — ограниченная учебная проверка своего экспорта, не полноценная валидация произвольного PDF.
Для удаления конфиденциальных данных из чужого документа нужны отдельная проверка и подходящий инструмент; этот урок такого обещания не даёт.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.