При работе в устаревших системах, таких как 1С:Предприятие 7.7, разработчики часто сталкиваются с аппаратными и программными ограничениями архитектуры. Одной из наиболее острых проблем является загрузка тяжелых файлов (от 100-200 МБ и выше) по защищенному протоколу HTTPS. Попытка использовать стандартные COM-объекты Windows часто приводит к аварийному завершению работы программы или ошибке «Недостаточно памяти для завершения операции».
В этой статье мы подробно проанализируем причины возникновения этой ошибки и разберем несколько надежных способов обхода ограничений платформы 7.7 с использованием внешних инструментов и системных возможностей Windows.
Рассмотрим стандартный подход, который часто пытаются применить программисты 1С. Использование объекта WinHttp.WinHttpRequest.5.1 в связке с ADODB.Stream кажется логичным, но таит в себе ловушку. Проанализируем типичный фрагмент кода:
WinHttp = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
WinHttp.Open("GET", URL, 0);
WinHttp.Send();
Если WinHttp.Status = 200 Тогда
ResponseBody = WinHttp.ResponseBody; // Ошибка возникает именно здесь
// ... запись в поток
КонецЕсли;
Причина сбоя заключается в том, что свойство ResponseBody пытается загрузить весь файл целиком в оперативную память процесса 1С в виде массива байтов (SafeArray). Поскольку 1С 7.7 — это 32-битное приложение, адресное пространство которого сильно ограничено, выделение непрерывного блока памяти объемом 500 МБ практически невозможно, особенно если память уже фрагментирована другими данными. Программа просто не может «переварить» такой объем данных за один раз.
Наиболее стабильным и производительным решением является использование консольной утилиты cURL. Она работает независимо от процесса 1С и эффективно управляет буферизацией данных, не нагружая оперативную память системы 1С.
Для реализации этого метода нам необходимо вызвать внешнее приложение через команду системы. Разберем, как правильно сформировать строку запуска, чтобы задать путь сохранения файла, о чем часто забывают пользователи.
Основные ключи для работы:
Рассмотрим пример кода в 1С 7.7:
Процедура СкачатьФайлЧерезCurl(АдресРесурса, ПутьКФайлу)
// Формируем команду. Используем кавычки для путей с пробелами.
Команда = "curl.exe -k -L -o """ + ПутьКФайлу + """ " + АдресРесурса;
// Запускаем через КомандаСистемы
КомандаСистемы(Команда);
// Проверяем наличие файла на диске после выполнения
ФС = СоздатьОбъект("ФС");
Если ФС.СуществуетФайл(ПутьКФайлу) = 1 Тогда
Сообщить("Файл успешно загружен: " + ПутьКФайлу);
Иначе
Сообщить("Ошибка загрузки файла через curl");
КонецЕсли;
КонецПроцедуры
Если у вас нет возможности установить стороннюю утилиту curl.exe, воспользуемся встроенным средством современных ОС Windows — PowerShell. Он доступен «из коробки» во всех версиях Windows, начиная с Windows 7 SP1.
Метод Invoke-WebRequest позволяет гибко скачивать файлы. Однако для очень больших файлов мы рекомендуем использовать .NET-класс WebClient, который работает быстрее в контексте командной строки.
Проанализируем пример команды:
ПутьКФайлу = "C:\temp\passports.csv";
URL = "https://server.com/data.zip";
// Формируем скрипт для PowerShell
Скрипт = "powershell -ExecutionPolicy Bypass -Command ""(New-Object System.Net.WebClient).DownloadFile('" + URL + "', '" + ПутьКФайлу + "')""";
КомандаСистемы(Скрипт);
Важный нюанс: Если сервер требует протокол TLS 1.2 (что сейчас является стандартом), PowerShell в старых системах может выдать ошибку. Чтобы этого избежать, нужно принудительно включить поддержку протокола в начале скрипта:
СкриптTLS = "powershell -Command ""[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; (New-Object System.Net.WebClient).DownloadFile(...)""";
Для загрузки файлов в фоновом режиме, особенно если интернет-соединение нестабильно, отлично подходит утилита BITSAdmin. Она использует службу фоновой интеллектуальной передачи данных (Background Intelligent Transfer Service).
Выясним преимущество этого метода: загрузка не прервется при кратковременном обрыве связи и не будет мешать работе пользователя, так как приоритет трафика можно настраивать.
Пример команды для 1С 7.7:
КомандаBITS = "bitsadmin /transfer MyDownloadJob /download /priority normal ""https://url/file.zip"" ""C:\download\file.zip""";
КомандаСистемы(КомандаBITS);
Выясним причину, по которой даже внешние вызовы могут не работать. В 1С 7.7 часто используются старые операционные системы (Windows Server 2008/2012). Если сайт перешел на современные стандарты шифрования, компонента WinHttp в коде 1С не сможет соединиться с сервером без правки реестра.
Чтобы заставить системные компоненты понимать TLS 1.2, необходимо убедиться, что в реестре по пути HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp установлен параметр DefaultSecureProtocols со значением 0x00000800 (для 32-битных систем).
После того как мы успешно скачали файл весом 500 МБ, возникает следующая проблема: как его прочитать в 1С 7.7? Рассмотрим типичную ошибку: попытка использовать объект Текст.
Объект Текст в 1С 7.7 при вызове метода Открыть() пытается загрузить весь текстовый файл в память. Это гарантированно приведет к вылету программы на файле в 500 МБ.
Рекомендация: Используйте объект FileSystemObject (FSO) для построчного чтения файла. Это позволит обрабатывать данные порциями, не перегружая память.
FSO = СоздатьОбъект("Scripting.FileSystemObject");
File = FSO.OpenTextFile(ПутьКФайлу, 1); // 1 = ForReading
Пока File.AtEndOfStream = 0 Цикл
СтрокаДанных = File.ReadLine();
// Обработка строки...
КонецЦикла;
File.Close();
Мы проанализировали проблему загрузки больших файлов через HTTPS в среде 1С 7.7 и пришли к выводу, что использование внутренних COM-объектов платформы для этой задачи нецелесообразно из-за ограничений памяти.
Основные выводы:
Текст или переменные типа Строка, используйте только построчное чтение через FileSystemObject.