Разработка в веб-клиенте 1С накладывает на программиста ряд специфических ограничений, которые отсутствуют в тонком или толстом клиентах. Одной из самых трудоемких задач является прямое взаимодействие с файловой системой пользователя. Часто разработчики сталкиваются с ошибками вроде "не удалось получить свойство closeasync" или внезапным закрытием браузера при попытке прочитать несколько байт из файла. В этой статье мы подробно разберем, как правильно организовать чтение данных из локального файла в браузере, какие объекты использовать и как избежать типичных ошибок.
Прежде всего, нам необходимо осознать, что любой современный браузер работает в режиме строгой изоляции («песочницы»). Программный код внутри страницы не имеет прямого доступа к диску C:\ или любым другим путям. Чтобы 1С могла взаимодействовать с файлами на стороне клиента в веб-интерфейсе, обязательно должно быть установлено и подключено Расширение для работы с файлами. Без него объект ФайловыйПоток просто не сможет инициализироваться, что и приводит к неопределенным значениям свойств в JavaScript-коде платформы.
Рассмотрим ситуацию, когда нам нужно прочитать первые несколько символов из файла. В обычном приложении мы бы просто использовали ЧтениеТекста, но в веб-клиенте нам доступны только асинхронные методы. Вызов синхронных методов работы с файлами в браузере заблокирован на уровне архитектуры платформы.
Для того чтобы прочитать данные непосредственно в браузере, нам потребуется комбинация объектов ФайловыйПоток и ЧтениеДанных. Проанализируем правильную последовательность действий. Сначала необходимо открыть поток, затем передать его в объект чтения и вызвать асинхронную процедуру получения данных.
Ниже приведен пример кода, который реализует это чтение. Обратите внимание на использование ОписаниеОповещения — это ключевой механизм для работы в веб-клиенте.
// Процедура инициации чтения
&НаКлиенте
Процедура ПрочитатьПервыеСимволы(ИмяФайла)
// Создаем объект потока для открытия файла
ОбъектФайловыйПоток = Новый ФайловыйПоток(ИмяФайла, РежимОткрытияФайла.Открыть, ДоступКФайлу.Чтение);
// Передаем поток в объект ЧтениеДанных
ОбъектЧтениеДанных = Новый ЧтениеДанных(ОбъектФайловыйПоток);
// Настраиваем оповещение о завершении чтения
Оповещение = Новый ОписаниеОповещения("ЗавершениеЧтенияСимволов", ЭтотОбъект, ОбъектЧтениеДанных);
// Запускаем асинхронное чтение первых 5 символов
ОбъектЧтениеДанных.НачатьЧтениеСимволов(Оповещение, 5);
КонецПроцедуры
&НаКлиенте
Процедура ЗавершениеЧтенияСимволов(Результат, ДополнительныеПараметры) Экспорт
// В переменной 'Результат' содержатся прочитанные данные
Сообщить("Прочитано: " + Результат);
// Обязательно закрываем объект чтения и поток
Чтение = ДополнительныеПараметры;
Чтение.Закрыть();
КонецПроцедуры
Разберем, почему возникает ошибка closeasync, упомянутая в обсуждениях. Эта ошибка часто свидетельствует о том, что объект ЧтениеДанных не был создан должным образом из-за проблем с правами доступа или отсутствия расширения. Когда выполнение доходит до попытки закрытия потока (которая в веб-клиенте тоже асинхронная), система пытается обратиться к методу closeasync у null-объекта.
Если ваша конфигурация работает на платформе версии 8.3.18 и выше, мы рекомендуем отказаться от цепочек ОписаниеОповещения в пользу оператора Ждать. Это значительно упрощает код и делает его линейным, что облегчает отладку в веб-клиенте.
Посмотрим на пример современного подхода:
&НаКлиенте
Асинхронная Процедура ПрочитатьФайлАсинхронно(ИмяФайла)
Попытка
Поток = Ждать ФайловыеПотоки.ОткрытьАсинхронно(ИмяФайла, РежимОткрытияФайла.Открыть);
Чтение = Новый ЧтениеДанных(Поток);
Данные = Ждать Чтение.ПрочитатьСимволыАсинхронно(5);
Сообщить("Результат: " + Данные);
Чтение.Закрыть();
Исключение
Сообщить("Ошибка при чтении: " + КраткоеОписаниеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецПроцедуры
Как показывает практика, работа с бинарными данными и потоками внутри браузера (особенно в устаревших версиях, таких как Internet Explorer) может быть нестабильной. Проанализируем ситуацию: если нам нужно всего 5 байт, не проще ли передать файл на сервер, где 1С обладает полным набором инструментов без ограничений браузера?
Алгоритм действий будет следующим:
НачатьПомещениеФайлаНаСервер (или ПоместитьФайлНаСерверАсинхронно).ДвоичныеДанные из этого хранилища.ЧтениеДанных уже на сервере, где он работает мгновенно и без расширений.Этот способ является наиболее надежным, так как он обходит проблемы с совместимостью различных браузеров и нестабильностью JavaScript-движков при работе с типизированными массивами данных.
При работе в веб-клиенте следует помнить о нескольких критических моментах:
C:\file.txt в браузере. Выбор файла всегда должен инициироваться пользователем через диалоговое окно (объект ДиалогВыбораФайла). Это требование безопасности всех современных браузеров.Закрыть() у объектов ЧтениеДанных и ФайловыйПоток. В веб-клиенте "зависшие" потоки могут привести к блокировке файла операционной системой до полной перезагрузки страницы браузера.Таким образом, мы выяснили, что чтение из файла в веб-клиенте — задача вполне решаемая. Главное — строго следовать асинхронной модели программирования 1С и не забывать про необходимость расширения работы с файлами для браузера.