ФайловыйПоток.Прочитать

Методы · Read

Выполняет чтение заданного количества байтов в указанный буфер по указанному смещению. Текущая позиция смещается вперед на фактическое количество прочитанных байтов. Чтение из потока возможно только, если поток поддерживает чтение. В противном случае, будет вызвано исключение. При чтении размер целевого буфера не меняется, а его содержимое перезаписывается фактически прочитанными данными. Если в буфере недостаточно места для записи прочитанных данных, происходит ошибка переполнения.

Синтаксис

Прочитать(<Буфер>, <ПозицияВБуфере>, <Количество>)
Полное описание, параметры и ограничения

ФайловыйПоток.Прочитать (FileStream.Read)

ФайловыйПоток (FileStream)

Прочитать (Read)

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

Синтаксис:
Прочитать(<Буфер>, <ПозицияВБуфере>, <Количество>)
Параметры:

<Буфер> (обязательный)
Тип: БуферДвоичныхДанных.
Буфер, в который выполняется чтение.

<ПозицияВБуфере> (обязательный)
Тип: Число.
Позиция в целевом буфере, начиная с которой требуется записывать данные из потока.

<Количество> (обязательный)
Тип: Число.
Количество байт, которые требуется записать в целевой буфер.
Возвращаемое значение:
Тип: Число.
Фактически прочитанное количество байтов. Может быть меньше,указанного, если достигнут конец потока.
Описание:

Выполняет чтение заданного количества байтов в указанный буфер по указанному смещению. Текущая позиция смещается вперед на фактическое количество прочитанных байтов.
Чтение из потока возможно только, если поток поддерживает чтение. В противном случае, будет вызвано исключение.
При чтении размер целевого буфера не меняется, а его содержимое перезаписывается фактически прочитанными данными. Если в буфере недостаточно места для записи прочитанных данных, происходит ошибка переполнения.

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

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

См. также:
Поток, метод НачатьЧтение
Поток, метод ПрочитатьАсинх

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

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

Описание изменено в версии 8.3.18.

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

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

Открывать собственный файл цепочкой Начать… и оповещений

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

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

Полный модуль собственной управляемой формы: callback-цепочка, локальный клиент Windows.

Подготовка

  1. Собственная учебная база 8.5.1.1343, тонкий или толстый клиент Windows с разрешённой локальной файловой системой. Создайте внешнюю обработку с управляемой формой, командой Выполнить и кнопкой; вставьте весь модуль одного урока.

  2. Это клиентский модуль, не серверный и не веб-клиентский: используются локальные файлы и операции потока, доступные этому окружению. Не отключайте профиль безопасности рабочей базы ради урока.

  3. Именованные уроки получают новое временное имя, резервируют его через СоздатьНовый и только после этого показывают методы, способные перезаписать собственный файл. Ни один путь не вводится пользователем.

  4. Автоматический временный поток создаётся менеджером без заданного имени. Не обещаем физический файл, его расположение или отсутствие файла на диске по одному свойству потока.

  5. Не закрывайте форму в середине асинхронной цепочки. После нормального завершения проверяйте сообщения очистки; при аварийном завершении клиента платформа может оставить временный файл до штатной уборки.

&НаКлиенте
Перем ВыполняетсяЦепочкаФайла;

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

&НаКлиенте
Функция ОповещениеФайла(Состояние)
    Возврат Новый ОписаниеОповещения("ПослеОткрытияФайла", ЭтаФорма, Состояние, "ОшибкаЦепочкиФайла", ЭтаФорма);
КонецФункции

&НаКлиенте
Процедура ПослеОткрытияФайла(Поток, Состояние) Экспорт
    Состояние.Поток = Поток;
    Попытка
        Если Состояние.Шаг = 0 Тогда
            Буфер = ПолучитьБуферДвоичныхДанныхИзСтроки("ABC", КодировкаТекста.UTF8, Ложь);
            Поток.Записать(Буфер, 0, 3);
            Состояние.Замена = ПолучитьБуферДвоичныхДанныхИзСтроки("Z", КодировкаТекста.UTF8, Ложь);
        ИначеЕсли Состояние.Шаг = 1 Тогда
            Поток.Записать(Состояние.Замена, 0, 1);
        ИначеЕсли Состояние.Шаг = 2 Тогда
            Прочитанный = Новый БуферДвоичныхДанных(3);
            Сообщить(Поток.Прочитать(Прочитанный, 0, 3) = 3);
            Сообщить(Прочитанный.Получить(0) = 90 И Прочитанный.Получить(1) = 66 И Прочитанный.Получить(2) = 67);
            Сообщить(Поток.ДоступноЧтение И НЕ Поток.ДоступнаЗапись);
        ИначеЕсли Состояние.Шаг = 3 Тогда
            Поток.Записать(Состояние.Замена, 0, 1);
        ИначеЕсли Состояние.Шаг = 4 Тогда
            Сообщить(Поток.Размер() = 4);
            Сообщить(Поток.ДоступноЧтение И Поток.ДоступнаЗапись);
        Иначе
            ВызватьИсключение "Неожиданный шаг собственной цепочки";
        КонецЕсли;
        Поток.Закрыть();
        Состояние.Поток = Неопределено;
        Состояние.Шаг = Состояние.Шаг + 1;
        Если Состояние.Шаг = 1 Тогда
            ФайловыеПотоки.НачатьОткрытиеДляЗаписи(ОповещениеФайла(Состояние), Состояние.Имя);
        ИначеЕсли Состояние.Шаг = 2 Тогда
            ФайловыеПотоки.НачатьОткрытиеДляЧтения(ОповещениеФайла(Состояние), Состояние.Имя);
        ИначеЕсли Состояние.Шаг = 3 Тогда
            ФайловыеПотоки.НачатьОткрытиеДляДописывания(ОповещениеФайла(Состояние), Состояние.Имя);
        ИначеЕсли Состояние.Шаг = 4 Тогда
            ФайловыеПотоки.НачатьОткрытие(ОповещениеФайла(Состояние), Состояние.Имя, РежимОткрытияФайла.Открыть, 8192);
        Иначе
            ОшибкаОчистки = ОчиститьФайлУрока(Состояние);
            ВыполняетсяЦепочкаФайла = Ложь;
            Если Не ПустаяСтрока(ОшибкаОчистки) Тогда
                ВызватьИсключение ОшибкаОчистки;
            КонецЕсли;
            Сообщить("Собственная цепочка завершена");
        КонецЕсли;
    Исключение
        ВыполняетсяЦепочкаФайла = Ложь;
        ОшибкаОперации = ОписаниеОшибки();
        ОшибкаОчистки = ОчиститьФайлУрока(Состояние);
        ВызватьИсключение ОшибкаОперации + " " + ОшибкаОчистки;
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура ОшибкаЦепочкиФайла(Ошибка, СтандартнаяОбработка, Состояние) Экспорт
    ВыполняетсяЦепочкаФайла = Ложь;
    ОшибкаОчистки = ОчиститьФайлУрока(Состояние);
    Если Не ПустаяСтрока(ОшибкаОчистки) Тогда
        Сообщить(ОшибкаОчистки);
    КонецЕсли;
    СтандартнаяОбработка = Истина;
КонецПроцедуры

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

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

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

  1. ПолучитьИмяВременногоФайла само не создаёт файл. Проверяем занятость и резервируем собственное имя через конструктор СоздатьНовый; чужое имя при конфликте не удаляется.

  2. Создать перезаписывает только уже созданный нами пустой файл. Записываем ASCII ABC без BOM — три байта 65, 66, 67.

  3. ОткрытьДляЗаписи пишет поверх начала: один байт Z=90 заменяет A. Ожидается ZBC, а не только Z; хвост не удаляется автоматически.

  4. ОткрытьДляЧтения возвращает поток без возможности записи. ОткрытьДляДописывания добавляет Z в конец: получается ZBCZ, четыре байта.

  5. Перед каждым повторным открытием предыдущий поток закрыт. Только собственный файл удаляется после успешного закрытия; ошибки операции и уборки сообщаются вместе.

  6. В ПослеОткрытияФайла ровно два аргумента: полученный Поток и ДополнительныеПараметры. Они передаются платформой, не конструируются из выдуманного исходного объекта.

  7. Состояние.Шаг задаёт пять этапов: создать, запись начала, чтение, дописывание, общее открытие. Следующий этап запускается только после закрытия предыдущего.

  8. ОписаниеОповещения содержит отдельный обработчик ошибки с тремя аргументами. СтандартнаяОбработка=Истина сохраняет штатное отображение ошибки.

  9. Флаг формы запрещает повторный старт во время цепочки; он сбрасывается при нормальном окончании и ошибке. Короткие операции самого потока здесь синхронные, это не веб-клиентский пример.

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

  1. Пять сравнений ожидаются Истина: прочитано три байта ZBC, чтение без записи, затем размер четыре и доступность чтения/записи.

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

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

Получена полная callback-цепочка пяти методов менеджера с реальным состоянием и очисткой.

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

  1. Не запускать все Начать… подряд вне callback: порядок завершения не будет гарантирован.

  2. Веб-клиент имеет другие ограничения локальных операций; наличие Начать… в справке не делает этот полный модуль веб-совместимым.

  3. НачатьСоздание перезаписывает файл; здесь он получает только имя, уже принадлежащее этому опыту.

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

Получить ZBCZ: перезапись начала, дописывание и два варианта Открыть

Полный клиентский опыт на одном собственном трёхбайтном файле с проверкой содержимого и очисткой.

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

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

Подготовка

  1. Собственная учебная база 8.5.1.1343, тонкий или толстый клиент Windows с разрешённой локальной файловой системой. Создайте внешнюю обработку с управляемой формой, командой Выполнить и кнопкой; вставьте весь модуль одного урока.

  2. Это клиентский модуль, не серверный и не веб-клиентский: используются локальные файлы и операции потока, доступные этому окружению. Не отключайте профиль безопасности рабочей базы ради урока.

  3. Именованные уроки получают новое временное имя, резервируют его через СоздатьНовый и только после этого показывают методы, способные перезаписать собственный файл. Ни один путь не вводится пользователем.

  4. Автоматический временный поток создаётся менеджером без заданного имени. Не обещаем физический файл, его расположение или отсутствие файла на диске по одному свойству потока.

  5. Не закрывайте форму в середине асинхронной цепочки. После нормального завершения проверяйте сообщения очистки; при аварийном завершении клиента платформа может оставить временный файл до штатной уборки.

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

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

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

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

  1. ПолучитьИмяВременногоФайла само не создаёт файл. Проверяем занятость и резервируем собственное имя через конструктор СоздатьНовый; чужое имя при конфликте не удаляется.

  2. Создать перезаписывает только уже созданный нами пустой файл. Записываем ASCII ABC без BOM — три байта 65, 66, 67.

  3. ОткрытьДляЗаписи пишет поверх начала: один байт Z=90 заменяет A. Ожидается ZBC, а не только Z; хвост не удаляется автоматически.

  4. ОткрытьДляЧтения возвращает поток без возможности записи. ОткрытьДляДописывания добавляет Z в конец: получается ZBCZ, четыре байта.

  5. Перед каждым повторным открытием предыдущий поток закрыт. Только собственный файл удаляется после успешного закрытия; ошибки операции и уборки сообщаются вместе.

  6. У синхронного Открыть первый вариант принимает РежимОткрытия, ИмяФайла, РазмерБуфера; второй — ДоступКФайлу, ИмяФайла, РежимОткрытия, РазмерБуфера. Порядок не такой, как у ОткрытьАсинх.

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

  1. Восемь сравнений ожидаются Истина; данные последовательно ABC → ZBC → ZBCZ.

  2. Последнее сообщение подтверждает удаление точного собственного временного файла. Нет такого сообщения при неудачной очистке.

  3. Не подставляйте пути ваших XML, HTML или рабочей базы вместо автоматически полученного имени.

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

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

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

  1. Создать может уничтожить прежнее содержимое. Он допустим здесь только после резервирования собственного имени.

  2. ОткрытьДляЗаписи не является гарантией усечения хвоста файла до размера новой записи.

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

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

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

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

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

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