Здравствуйте. На Клиенте с помощью предназначенного для этого метода происходит интерактивный выбор файла XML пользователем (по сути это текстовый файл), файл записывается во временное хранилище.

Затем на сервере значение из временного хранилища необходимо получить в виде строки-содержимого.
В данный момент использую следующий код:

```1c
    ДвоичныеДанныеКонтейнера = ПолучитьИзВременногоХранилища(ПараметрыАдресФайла);
    Если ДвоичныеДанныеКонтейнера = Неопределено Тогда
    ТекстОшибки = "Не удалось прочитать файл с контейнером.";
    Иначе
    Попытка
    ЧтениеДанных = Новый ЧтениеДанных(ДвоичныеДанныеКонтейнера);
    ЧтениеДанных.КодировкаТекста = КодировкаТекста.UTF8;
    ЧтениеТекста = Новый ЧтениеТекста(ЧтениеДанных.ИсходныйПоток(), КодировкаТекста.UTF8);
    СтрокаXML = ЧтениеТекста.Прочитать();
    ЧтениеТекста.Закрыть();
    ЧтениеДанных.Закрыть();
    Исключение
    ТекстОшибки = "Не удалось получить строку XML из файла.";
    КонецПопытки;
    КонецЕсли;
```

1) Является ли этот код оптимальным и правильным для поставленной задачи на современных платформах?
2) Есть ли способ решить подобную задачу на платформах до 8.3.9, в которых объект ЧтениеДанных отсутствовал?
---
1. Правильным - да, оптимальным - нет, т.к. происходит чтение всего файла XML в ОЗУ.
2. Как-то так:

```1c
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
    ДвоичныеДанныеКонтейнера = ПолучитьИзВременногоХранилища(ПараметрыАдресФайла);

    ДвоичныеДанныеКонтейнера.Записать(ИмяВременногоФайла);

    Поток = Новый ЧтениеXML;
    Поток.Открыть(ИмяФайла);

    Пока Поток.Прочитать() Цикл
    Пока Поток.ТипУзла = ТипУзлаXML.НачалоЭлемента И Поток.Имя = "НужноеИмяТэгаОбъекта" Цикл
    ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(Поток);
    ..............
    КонецЦикла;
    КонецЦикла;
    Поток.Закрыть();
    УдалитьФайлы(ИмяВременногоФайла);
```
---
через ДиалогВыбораФайла можно получить имя файла и прочитать

```1c
    Режим = РежимДиалогаВыбораФайла.Открытие;
    ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(Режим);
    ДиалогОткрытияФайла.ПолноеИмяФайла = ";
    Фильтр = "Файл xml|*.xml";
    ДиалогОткрытияФайла.Фильтр = Фильтр;
    ДиалогОткрытияФайла.Заголовок = "Выберите файл";
    Если ДиалогОткрытияФайла.Выбрать() Тогда
    ИмяФайла = ДиалогОткрытияФайла.ПолноеИмяФайла;
    Чтение = Новый ЧтениеТекста(ИмяФайла);
    Текст = Чтение.Прочитать();
    НужнаяПроцедураНаСервере(Текст);
    Иначе
    Предупреждение("Файл не выбран!");
    КонецЕсли;
```

Но да, на веб клиенте не доступно, но и в (1) про него не упоминалось.
Тогда для веб клиента можно на сервере читать через ЧтениеТекста вместо ЧтениеДанных.
---
1. Правильным - да, оптимальным - нет, т.к. происходит чтение всего файла XML в ОЗУ.
2. Как-то так:

```1c
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
    ДвоичныеДанныеКонтейнера = ПолучитьИзВременногоХранилища(ПараметрыАдресФайла);

    ДвоичныеДанныеКонтейнера.Записать(ИмяВременногоФайла);

    Поток = Новый ЧтениеXML;
    Поток.Открыть(ИмяФайла);

    Пока Поток.Прочитать() Цикл
    Пока Поток.ТипУзла = ТипУзлаXML.НачалоЭлемента И Поток.Имя = "НужноеИмяТэгаОбъекта" Цикл
    ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(Поток);
    ..............
    КонецЦикла;
    КонецЦикла;
    Поток.Закрыть();
    УдалитьФайлы(ИмяВременногоФайла);
```
---
Этот вариант тоже читает файл в память - метод получения двочиных данных.

Вообще, если делать быстро, то надо вообще вот так делать (при файлах не очень большого размера):
Код&НаКлаенте
Процедура ОбработатьКлиент(ИмяФайла)
  ОбработатьСервер( Новый ДвоичныеДанные( ИмяФайла ) );
КонецПроцедуры

Процедура ОбработатьСервер( ДД )
  Поток = Новый ПотокВПамяти ( ДД );
  ЧтениеХМЛ = Новый ЧтениеХМЛ( Поток );
  // какое-то шаманство
  ЧтениеХМЛ.Закрыть();
КонецПроцедуры
Показать полностьюНу все слова в синтаксис-помощнике подглядеть труда не составит...
---
Это был вариант для старых релизов. Там ключевое - предварительное сохранение файла на диск.
---
вариант для старых релизовНу так можно просто сохранить, потом ДД = ""; - все, память очистили. Потом прочитать из файла уже по старорежжимному...
---
в первом случае файл целиком читается в ОЗУ, а в случае, что описал я - нет, в этом принципиальное отличие подходов.

Если чтение в виде двоичных данных можно делать как-то частями и при этом прочитанную часть можно обработать, то делать нужно именно так.
---
А это:
```1c
    ДвоичныеДанныеКонтейнера = ПолучитьИзВременногоХранилища(ПараметрыАдресФайла);

    ДвоичныеДанныеКонтейнера.Записать(ИмяВременногоФайла);
```

Это не чтение файла целиком в ОЗУ? Двоичные данные контейнера что содержат?
При получении на сервере значения из временного хранилища следует учитывать то, что оно получается по ссылке. В действительности, ссылка эта указывает на значение, которое хранится в кеше. В течение 20 минут, с момента помещения в хранилище или же с момента последнего обращения, значение сохранится в кеше, а затем записывается на диск и из кеша удаляется. При следующем обращении значение загружается с диска и снова помещается в кеш.
Фактически, кеш - это память, которая через 20 минут выгрузится на диск. При варианте с двоичными данными, передаваемыми на сервер, память экономится только на клиенте.
---
хорошо. Убираем помещение ДД во ВрХр и получение из него - читаем XML и формируем ОбъектXDTO прямо на клиенте.
---
ОбъектXDTO прямо на клиентеВ принципе даже работает, но не все. Объект XDTO - это тоже все в памяти, поэтому лучше последовательно читать, особенно если файл большой. По крайней мере результат вебсервиса - объект тот самый - не ездит между сервером и клиентом, ну и веб-сервисы на клиенте не работают.

Если файло большое, то совсем правильно читать его и скармливать фоновым заданиям прочитанное (по сотне единиц, например).
---
Я ж привел пример чтения по одному ОбъектXDTO - он занимает минимально возможное для своего существования место в ОЗУ.

А вот х.з., можно будет ОбъектXDTO, сформированный на клиенте передать на сервер или нет :)
---
впринципе, для объекта XDTO у 1С есть своя модель данных в базовых пакетах, т.е. он вроде как сериялизуется, а все, что сериализуется, может ездить туды-сюды, если там и сям доступно.
---
На Клиенте с помощью предназначенного для этого метода происходит интерактивный выбор файла XML пользователем (по сути это текстовый файл), файл записывается во временное хранилище.
(1) Есть ли способ решить подобную задачу на платформах до 8.3.9, в которых объект ЧтениеДанных отсутствовал?
Можно на клиенте читать не двоичные данные, а сразу текст (ЧтениеТекста) и его передавать.
---
Я понял идею, но не понял реализацию, уточните пожалуйста. ЧтениеТекста получает файл по пути в системе, а не выбирает его интерактивно, кроме того, оно недоступно на веб-клиенте. Методы для работы с файловой системой (такие как НачатьПомещениеФайлаНаСервер) все и во всех платформах помещают файл в виде двоичных данных во временное хранилище.
---
через ДиалогВыбораФайла можно получить имя файла и прочитать

```1c
    Режим = РежимДиалогаВыбораФайла.Открытие;
    ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(Режим);
    ДиалогОткрытияФайла.ПолноеИмяФайла = ";
    Фильтр = "Файл xml|*.xml";
    ДиалогОткрытияФайла.Фильтр = Фильтр;
    ДиалогОткрытияФайла.Заголовок = "Выберите файл";
    Если ДиалогОткрытияФайла.Выбрать() Тогда
    ИмяФайла = ДиалогОткрытияФайла.ПолноеИмяФайла;
    Чтение = Новый ЧтениеТекста(ИмяФайла);
    Текст = Чтение.Прочитать();
    НужнаяПроцедураНаСервере(Текст);
    Иначе
    Предупреждение("Файл не выбран!");
    КонецЕсли;
```

Но да, на веб клиенте не доступно, но и в (1) про него не упоминалось.
Тогда для веб клиента можно на сервере читать через ЧтениеТекста вместо ЧтениеДанных.
---
Действительно, если вся задача – это получить СтрокаXML на сервере, то достаточно передать строку в параметрах серверной процедуры, минуя и временное хранилище и объекты работы с данными.
---
Это было бы прекрасно, только расскажите мне как интерактивно выбрать файл на клиенте и получить из него строку-содержимое тоже на клиенте, с учетом поддержки всех видов клиента (см. ответ (14)).