При попытке прочитать сохраненную HTML-страницу или текстовый файл в кодировке UTF-8 средствами платформы 1С:Предприятие 7.7 (например, через штатный объект Текст или объект V7TextFile из компоненты v7plus.dll) вместо русских букв часто отображаются некорректные символы («козябры»).
Разберем подробнее, почему возникают эти искажения и как заставить 1С 7.7 правильно обрабатывать файлы в формате UTF-8.
Проанализируем работу встроенных механизмов платформы 1С 7.7. Штатный объект Текст и компонента v7plus.dll (объект V7TextFile) проектировались для работы с однобайтовыми кодировками. Метод КодоваяСтраница() поддерживает переключение только между кодировками Windows-1251 (ANSI) и CP866 (DOS). Нативная поддержка многобайтовых кодировок, таких как UTF-8, на уровне платформы 1С 7.7 отсутствует.
Кроме того, при сохранении текстового файла в UTF-8 многие редакторы добавляют в начало файла трехбайтовый маркер BOM (Byte Order Mark) — EF BB BF. Поскольку платформа не умеет его автоматически распознавать и пропускать, в начале первой строки при прочтении могут добавляться спецсимволы вроде п»ї.
Для корректного чтения файлов в кодировке UTF-8 воспользуемся системным COM-объектом ADODB.Stream, входящим в состав компонентов ADO (ActiveX Data Objects). Данный компонент установлен практически во всех операционных системах Windows.
Рассмотрим по шагам процесс выгрузки и чтения файла с помощью ADODB.Stream:
ADODB.Stream.Type = 2) и указываем кодировку Charset = "utf-8".Open() и загружаем содержимого файла методом LoadFromFile().ReadText(). Объект автоматически выполнит преобразование символов из UTF-8 в кодовую страницу Windows-1251, которую 1С 7.7 воспринимает корректно.Посмотрим на пример кода чтения файла в кодировке UTF-8:
// Создаем объект для работы с потоком данных
Stream = СоздатьОбъект("ADODB.Stream");
// Задаем параметры потока
Stream.Type = 2; // 2 - Text data
Stream.Charset = "utf-8";
// Открываем поток и загружаем файл
Stream.Open();
Stream.LoadFromFile("C:\files\page.html");
// Считываем весь текст файла в переменную 1С
ТекстСтраницы = Stream.ReadText();
// Закрываем поток
Stream.Close();
// Теперь переменная ТекстСтраницы содержит корректный русский текст
Сообщить(ТекстСтраницы);
Если содержимое файла необходимо передать для дальнейшей регулярной обработки штатным объектом Текст, мы можем выполнить двухпотоковую перекодировку файла и сохранить его в ANSI-кодировке.
Рассмотрим пример кода, который конвертирует файл из UTF-8 в Windows-1251:
ПутьКФайлуUTF8 = "C:\files\input_utf8.html";
ПутьКФайлуANSI = "C:\files\output_ansi.html";
// Поток для чтения исходного файла в UTF-8
InStream = СоздатьОбъект("ADODB.Stream");
InStream.Type = 2;
InStream.Charset = "utf-8";
InStream.Open();
InStream.LoadFromFile(ПутьКФайлуUTF8);
// Считываем содержимое
Содержимое = InStream.ReadText();
InStream.Close();
// Поток для записи нового файла в Windows-1251
OutStream = СоздатьОбъект("ADODB.Stream");
OutStream.Type = 2;
OutStream.Charset = "windows-1251";
OutStream.Open();
OutStream.WriteText(Содержимое);
// Сохраняем перекодированный файл (2 - перезаписать существующий)
OutStream.SaveToFile(ПутьКФайлуANSI, 2);
OutStream.Close();
После выполнения этого кода перекодированный файл output_ansi.html можно открывать стандартным методом 1С 7.7:
ОбъектТекст = СоздатьОбъект("Текст");
ОбъектТекст.КодоваяСтраница(0); // 0 - кодировка Windows (ANSI)
ОбъектТекст.Открыть(ПутьКФайлуANSI);
Если основной задачей является не просто чтение файла, а именно разбор HTML-кода (извлечение текста без тегов, поиск элементов), можно использовать специализированный системный объект htmlfile.
Разберем пример загрузки HTML-кода в модель DOM:
// Сначала считываем HTML-файл без искажений через ADODB.Stream
Stream = СоздатьОбъект("ADODB.Stream");
Stream.Type = 2;
Stream.Charset = "utf-8";
Stream.Open();
Stream.LoadFromFile("C:\files\page.html");
HTMLКод = Stream.ReadText();
Stream.Close();
// Загружаем полученный код в документ HTML DOM
HTMLДокумент = СоздатьОбъект("htmlfile");
HTMLДокумент.write(HTMLКод);
// Извлекаем чистый текст без HTML-тегов
ТекстБезТегов = HTMLДокумент.body.innerText;
Сообщить(ТекстБезТегов);
Обратите внимание: при передаче длинных строк через интерфейс OLE/COM (например, при вызове метода ReadText() для файлов объемом более нескольких мегабайт) платформа 1С 7.7 может завершить работу с ошибкой из-за системного ограничения на размер строки в переменной. Для обработки файловых массивов сверхбольшого размера рекомендуется выполнять конвертацию файла целиком на диске или вычитывать его блоками.