Работа с внешними данными — одна из самых частых задач при разработке в среде 1С:Предприятие. Часто возникает необходимость загрузить информацию из простого текстового документа, будь то список артикулов, выгрузка логов или импорт справочника из сторонней системы. В отличие от табличных документов или XML, текстовые файлы требуют особого подхода к чтению посимвольно или построчно, чтобы корректно обработать поток данных.

В платформе 1С:Предприятие 8 для этих целей существует мощный встроенный механизм класса ТекстовыйДокумент и объекта чтения. Этот инструмент позволяет разработчику гибко управлять процессом: от выбора кодировки до обработки разделителей строк, что критически важно при работе с файлами, пришедшими от внешних контрагентов.

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

Основные объекты для работы с текстом в 1С

Для начала работы с файловой системой платформы необходимо создать экземпляр специального объекта, предназначенного для чтения. В 1С не стоит путать объект для чтения и объект для записи, так как они имеют разный набор методов и свойств. Фундаментальным элементом здесь выступает объект ЧтениеТекста. Именно он открывает доступ к содержимому файла, предоставляя методы для последовательного извлечения информации.

Создание объекта происходит стандартным способом через конструктор. После создания важно сразу же открыть файл, указав его полный путь. Если файл находится в каталоге данных конфигурации, путь нужно формировать динамически, используя функцию КаталогДанных() или КаталогВременныхФайлов(). Это обеспечивает кроссплатформенность кода и корректную работу как в файловом, так и в клиент-серверном варианте работы.

⚠️ Внимание: При попытке открыть файл, который в данный момент занят другим процессом (например, открыт в Блокноте или Excel), система 1С выдаст исключение. Всегда оборачивайте операцию открытия в конструкцию Попытка..Исключение, чтобы gracefully обработать ошибку доступа.

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

Алгоритм построчного чтения файла

Самый распространенный сценарий использования — это чтение файла строка за строкой. Такой подход оптимален для обработки CSV-файлов, списков номенклатуры или конфигурационных параметров. Цикл чтения должен продолжаться до тех пор, пока метод проверки конца файла не вернет истину. Для этого используется метод КонецФайла().

Внутри цикла мы вызываем метод ПрочитатьСтроку(). Он возвращает содержимое текущей строки и автоматически перемещает указатель на следующую. Полученную строку можно сразу же обрабатывать: разбивать на поля, искать подстроки или записывать во временную таблицу значений. Такой подход позволяет экономить оперативную память, так как мы не загружаем весь огромный файл в переменную целиком.

☑️ Алгоритм чтения файла

Выполнено: 0 / 5

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

Процедура ПрочитатьФайлПострочно(ИмяФайла)

Чтение = Новый ЧтениеТекста;

Попытка

Чтение.Открыть(ИмяФайла);

Исключение

Сообщить("Ошибка открытия файла: " + ОписаниеОшибки());

Возврат;

КонецПопытки;

Пока Не Чтение.КонецФайла() Цикл

Строка = Чтение.ПрочитатьСтроку();

// Здесь логика обработки строки

Сообщить(Строка);

КонецЦикла;

Чтение.Закрыть();

КонецПроцедуры

Важно отметить, что метод ПрочитатьСтроку() автоматически удаляет символы перевода строки (CR/LF) из конца считанной строки. Вам не нужно выполнять дополнительную очистку от этих символов, что упрощает парсинг данных. Однако, если в файле используются нестандартные разделители, это придется учитывать при дальнейшей обработке.

Особенности пустых строк

Если в файле встречаются пустые строки, метод ПрочитатьСтроку() вернет пустую строку "", а не пропустит её. Вам нужно самостоятельно добавить проверку: Если Длина(Строка) > 0 Тогда.. для пропуска пустых записей.

Работа с кодировками и спецсимволами

Одной из главных проблем при импорте данных является несоответствие кодировок. Файл может быть сохранен в UTF-8, Windows-1251 или UTF-16 (Unicode). Если 1С попытается прочитать файл в неверной кодировке, вместо текста вы увидите набор непонятных символов. Объект ЧтениеТекста позволяет явно указать требуемую кодировку при открытии файла.

Для этого используется перечисление КодировкаТекста. Вы можете передать его вторым параметром в метод Открыть. Если параметр не указан, 1С попытается определить кодировку автоматически по BOM (Byte Order Mark), но этот механизм работает не всегда корректно, особенно с файлами без метки BOM в кодировке UTF-8 без BOM.

💡

Если вы работаете с файлами, экспортированными из зарубежных систем или веб-сервисов, чаще всего они имеют кодировку UTF-8. Принудительно указывайте КодировкаТекста.UTF8 при открытии, чтобы избежать проблем с кириллицей.

Также стоит упомянуть о разделителях строк. В разных операционных системах они могут отличаться: в Windows это пара символов CR+LF, в Unix/Linux и macOS — одиночный LF. Объект чтения в 1С универсален и корректно обрабатывает оба варианта, поэтому кроссплатформенность кода обеспечивается "из коробки". Вам не нужно писать условия для определения ОС.

Тип кодировки Описание Рекомендация использования
Авто Определяется по BOM Для файлов, созданных в Windows
UTF-8 Универсальная кодировка Для обмена с веб-сервисами и Linux
Windows-1251 Стандартная русская кодировка Для старых систем и отчетов
UTF-16 Юникод (2 байта на символ) Редко используется для текстовых обменов

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

📊 С какой кодировкой файлов вы сталкиваетесь чаще всего?
Windows-1251
UTF-8
UTF-16
Не знаю, работаю только с Excel

Чтение всего содержимого файла целиком

Иногда построчная обработка избыточна. Если файл небольшой (несколько килобайт) и его структура сложна, удобнее считать всё содержимое в одну строковую переменную. Для этого в объекте ЧтениеТекста существует метод ПрочитатьВесьТекст(). Он возвращает одну длинную строку, содержащую весь файл, включая все символы перевода строки.

Такой метод удобен для чтения JSON, XML (хотя для них есть свои специализированные читатели) или конфигов. После получения всей строки вы можете использовать методы работы со строками: СтрЗаменить, СтрНайти, СтрРазделить. Это дает полный контроль над данными, но требует больше оперативной памяти.

Использование этого подхода оправдано, когда логика обработки зависит от контекста нескольких строк сразу. Например, если нужно найти блок текста между двумя маркерами, которые могут находиться на разных строках. В построчном режиме это потребовало бы сложной логики с накопителем строк, а при чтении всего текста решается одной функцией поиска подстроки.

⚠️ Внимание: Никогда не используйте ПрочитатьВесьТекст() для файлов размером более 10-20 Мб. Это может привести к зависанию клиента 1С из-за выделения огромного объема памяти под одну строковую переменную и последующей сборки мусора.

Пример использования метода:

Чтение = Новый ЧтениеТекста;

Чтение.Открыть(ПутьКФайлу);

ВесьТекст = Чтение.ПрочитатьВесьТекст();

Чтение.Закрыть();

// Обработка как единого массива

МассивСтрок = СтрРазделить(ВесьТекст, Символы.ПС, Ложь);

Обратите внимание на второй параметр функции СтрРазделить. Если передать Ложь, то пустые строки, образовавшиеся в результате разбиения, будут включены в результат. Если Истина — они будут отброшены. Выбор зависит от требований к данным.

Обработка ошибок и исключительных ситуаций

Работа с файлами всегда сопряжена с рисками: файл может быть удален, перемещен, заблокирован антивирусом или поврежден. В 1С любая ошибка ввода-вывода генерирует исключение. Если не перехватить его, выполнение кода прервется, и пользователь увидит стандартное красное окно с техническим текстом ошибки, что является плохим тоном в разработке.

Используйте конструкцию Попытка.. Исключение.. КонецПопытки вокруг всех операций с файловой системой. Внутри блока Исключение используйте функцию ОписаниеОшибки() для получения человекочитаемого текста проблемы. Это позволит вывести понятное сообщение пользователю или записать детали в журнал регистрации.

Особое внимание уделите блоку Попытка при закрытии файла. Даже если чтение прошло успешно, ошибка может возникнуть в момент закрытия (редко, но бывает при сетевых сбоях). Рекомендуется выносить операцию Закрыть() в отдельный блок или использовать конструкцию Попытка внутри основного цикла обработки, если критична непрерывность процесса.

💡

Всегда закрывайте объект ЧтениеТекста в блоке Исключение или в гарантии (если бы она была в 1С), чтобы избежать утечки дескрипторов файлов операционной системы.

Также стоит проверять существование файла перед попыткой чтения, используя функцию ФайлСуществует(ИмяФайла). Хотя это не заменяет обработку исключений (файл могут удалить между проверкой и открытием), это позволяет избежать лишней генерации исключений в штатных ситуациях, когда файла просто нет.

Сравнение методов чтения и выбор оптимального

Выбор между построчным чтением и чтением всего текста зависит от конкретной задачи. Нет универсального решения, которое подходило бы всегда. Разработчик должен оценивать объем данных, структуру файла и доступные ресурсы сервера или клиента.

Построчное чтение (ПрочитатьСтроку) является наиболее эффективным с точки зрения памяти. Оно позволяет обрабатывать гигабайтные логи, не загружая оперативную память. Однако скорость обработки может быть ниже из-за большого количества вызовов методов и переходов между контекстами выполнения.

Чтение всего текста (ПрочитатьВесьТекст) работает быстрее для малых объемов данных, так как минимизирует количество обращений к диску и объектной модели. Но цена этой скорости — высокое потребление RAM. Для файлов среднего размера (1-5 Мб) разница может быть незаметна, но на больших объемах она становится критичной.

Критерий Построчное чтение Чтение всего текста
Потребление памяти Минимальное Высокое (размер файла x 2)
Скорость (малые файлы) Средняя Высокая
Сложность кода Выше (нужен цикл) Низкая (одна строка)
Обработка больших файлов Возможна Не рекомендуется

Если ваша задача — просто скопировать файл или передать его содержимое в веб-сервис без анализа, используйте потоковое чтение или чтение в двоичном виде, если текст не требуется. Но для парсинга данных внутри 1С описанные выше методы являются стандартом де-факто.

Часто задаваемые вопросы (FAQ)

Как прочитать файл, если я не знаю его кодировку?

Попробуйте открыть файл без указания кодировки. 1С попытается определить её по BOM. Если результат некорректен, переберите основные варианты (UTF-8, Windows-1251) в цикле с обработкой исключений или визуальной проверкой первых строк, пока не получите читаемый текст.

Можно ли читать текстовый файл на клиенте в тонком клиенте?

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

Как обработать файл, разделенный табуляцией (TSV)?

Используйте метод СтрРазделить(Строка, Символы.Таб, Ложь) после чтения строки. Это разобьет строку на массив полей. Не забудьте обработать случай, когда количество полей в строке отличается от ожидаемого.

Что делать, если файл очень большой и 1С зависает?

Перейдите на построчное чтение и обрабатывайте данные пакетами. Например, считывайте 1000 строк, записывайте их в базу данных, очищайте временные структуры и продолжайте чтение. Это снизит пиковую нагрузку на память и процессор.

Как узнать текущую позицию чтения в файле?

В стандартном объекте ЧтениеТекста нет свойства для получения текущей позиции в байтах или строках. Если вам это критично, вам придется вести счетчик строк вручную внутри цикла чтения.