Как правильно обрабатывать файлы большого объема в 1С и почему не работает метод УдалитьСтроку

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с внешними данными программисты 1С часто сталкиваются с необходимостью обработки текстовых файлов колоссальных объемов — 10, 15 и более гигабайт. В таких ситуациях возникают закономерные опасения по поводу стабильности системы и потребления оперативной памяти. Попытки реализовать алгоритм «прочитал — удалил — сохранил» часто приводят к ошибке «Метод объекта не обнаружен (УдалитьСтроку)». В этой статье мы подробно разберем, почему возникает эта ошибка, как на самом деле платформа 1С работает с памятью при чтении файлов и какие методы обработки являются наиболее эффективными.

Причина ошибки «Метод объекта не обнаружен (УдалитьСтроку)»

Разберем ситуацию, представленную в коде автора темы. Для чтения данных используется объект ЧтениеТекста. Попытка вызвать метод УдалитьСтроку() у этого объекта всегда будет приводить к ошибке, так как этого метода просто не существует в программном интерфейсе (API) данного класса.

Проанализируем разницу между объектами, предназначенными для работы с текстом в 1С:

  1. ЧтениеТекста: Это специализированный объект-стрим (поток). Он предназначен исключительно для последовательного извлечения данных из файла. Он умеет «смотреть» в файл, но не умеет его изменять.
  2. ТекстовыйДокумент: Этот объект действительно имеет метод УдалитьСтроку(). Однако использование этого объекта для файлов объемом 15 ГБ категорически противопоказано. ТекстовыйДокумент при открытии файла пытается полностью загрузить его содержимое в оперативную память. В случае с файлом на 15 ГБ это приведет к немедленному падению сеанса 1С с ошибкой «Нехватка памяти».

Таким образом, автор пытался применить метод от одного объекта (интерактивного редактора) к другому объекту (потоковому чтецу), что и вызвало технический сбой.

Миф о переполнении памяти при чтении больших файлов

Основное заблуждение многих разработчиков заключается в том, что чтение файла объемом 15 ГБ «забьет» всю оперативную память сервера. Это не так. Выясним причину, почему последовательное чтение безопасно:

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

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

Почему удаление строк из начала файла — плохая идея

Рассмотрим физику процесса работы жесткого диска и файловой системы (NTFS или FAT32). Файл на диске — это последовательность байтов. Вы не можете просто «вырезать» первые 150 000 строк из файла без последствий. Чтобы удалить данные из начала, операционная система должна взять все оставшиеся 14,9 ГБ данных и физически перезаписать их, сдвигая в начало файла, чтобы закрыть образовавшуюся «дыру».

Если выполнять такую операцию циклично (прочитал порцию — перезаписал 15 ГБ), процесс растянется на недели, а ресурс дисковой подсистемы будет исчерпан крайне быстро из-за колоссальной нагрузки на ввод-вывод (I/O). Поэтому алгоритм «удаления прочитанного» для текстовых логов является самым медленным и ресурсоемким из всех возможных.

Решение №1: Последовательное чтение (рекомендуемое)

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


Текст = Новый ЧтениеТекста;
Текст.Открыть(ПолноеИмяФайла, КодировкаТекста.UTF8);

Стр = Текст.ПрочитатьСтроку();
Пока Стр <> Неопределено Цикл
    // Выполняем необходимую обработку данных строки
    ОбработатьДанные(Стр);
    
    // Переходим к следующей строке
    Стр = Текст.ПрочитатьСтроку();
КонецЦикла;

Текст.Закрыть();

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

Решение №2: Использование позиции для прерывистой обработки

Если задача состоит в том, чтобы обрабатывать файл порциями (например, по 150 000 строк в рамках регламентного задания), и вы боитесь, что процесс прервется, используйте смещение (позицию) вместо удаления строк. Для этого в современной платформе 1С 8.3 используются объекты ФайловыйПоток и ЧтениеДанных.

Разберем алгоритм по шагам:

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

Пример кода для работы с позицией:


// Открываем поток для чтения
Поток = Новый ФайловыйПоток(ПолноеИмяФайла, РежимОткрытияФайла.Открыть, ДоступКФайлу.Чтение);
Чтение = Новый ЧтениеДанных(Поток);

// Если у нас сохранена позиция с прошлого раза
Если ЕстьСохраненнаяПозиция Тогда
    Поток.Перейти(СохраненноеЗначениеПозиции, РежимПеремещенияВПотоке.Начало);
КонецЕсли;

Для Счетчик = 1 По 150000 Цикл
    СтрокаДанных = Чтение.ПрочитатьСтроку();
    Если СтрокаДанных = Неопределено Тогда
        Прервать;
    КонецЕсли;
    Обработать(СтрокаДанных);
КонецЦикла;

// Сохраняем текущую позицию потока для следующего запуска
СохраненноеЗначениеПозиции = Поток.ТекущаяПозиция();
Чтение.Закрыть();

Решение №3: Разрезание файла (Splitting)

Если файл слишком велик для обработки одним потоком и вы хотите запустить несколько фоновых заданий параллельно, проанализируем вариант «разрезания» файла. Вместо того чтобы мучить 1С операциями удаления, воспользуйтесь системными утилитами. В Linux это команда split, в Windows можно использовать аналоги на PowerShell или сторонние бесплатные утилиты. Вы можете один раз разрезать 15-гигабайтный файл на 15 файлов по 1 ГБ и обрабатывать их независимо. Это значительно ускорит работу и упростит логику приложения.

Подведение итогов

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

← На главную