Синтаксис и применение ПараметрыДиалогаПомещенияФайлов.По умолчанию в платформе 1С:Предприятие. Описание и примеры кода.
Синтаксис
Новый ПараметрыДиалогаПомещенияФайлов()Полное описание, параметры и ограничения
ПараметрыДиалогаПомещенияФайлов.По умолчанию
ПараметрыДиалогаПомещенияФайлов (PutFilesDialogParameters)
По умолчанию
Доступен, начиная с версии 8.3.15.
Синтаксис:
Новый ПараметрыДиалогаПомещенияФайлов()
Использование в версии:
Доступен, начиная с версии 8.3.15.
Методическая информация
Практические примеры
Собственная UTF8-пара: ссылки на файлы, помещение с оповещениями и чтение через Ждать
Полный учебный маршрут с собственными данными и настоящими объектами платформы. Две записи UTF8, новые UUID, точные параметры оповещений, сопоставление по имени и независимое чтение результата. Отмена и ограничения выбора папки объясняются отдельно.
Где и как запускать
Полный модуль своей управляемой формы новой пустой файловой ИБ 8.5.1.1343. Толстый управляемый Windows x64 клиент; сервер только проверяет пустой стенд и временные данные. Фактические UI/files/1C/network операции: 0.
Подготовка
Создайте новую собственную пустую файловую информационную базу на платформе 8.5.1.1343. Имя корня конфигурации — УчебныеСсылкиИПередачаФайлов85. Русский встроенный язык, управляемое приложение, совместимость «Не использовать». Не берите рабочую базу или чужие файлы. В конфигурации нет справочников, документов, регистров, планов, задач, подписок, заданий, общих реквизитов, внешних источников и расширений.
Запускайте только толстый управляемый клиент Windows x64 под отдельным учебным профилем Windows. Справка разрешает многие эти API также в тонком, веб- и мобильном клиентах, но там отличаются доступ к файлам и диалоги. Эти варианты здесь не заявляются проверенными. Расширения браузера и внешние сервисы для выбранного маршрута не нужны.
Создайте внешнюю обработку OwnFileTransfer85 и одну управляемую форму. Реквизиты: ПодтверждаюСвойСтенд85 — Булево, начально Ложь; Занято85 — Булево, начально Ложь, ТолькоПросмотр; ПутьОпыта85 — Строка неограниченной длины, ТолькоПросмотр; Статус85 — такая же Строка, многострочная, ТолькоПросмотр. Вставьте целиком модуль выбранной карточки; два модуля не объединяйте.
Для помещения файлов на сервер добавьте реквизит ОтменитьПередНачалом85 — Булево, начально Ложь. Создайте команды и кнопки: СоздатьСвоюПару85, ПоместитьСОбычнымиПараметрами85, ПоместитьСКонструктором85, ПрочитатьСвоиFileRef85. Параметр Команда передает сама кнопка. Оповещения связывают экспортные обработчики с событиями завершения, прогресса, начала и ошибки передачи.
Download форма дополнительно: ПодтверждаюТолькоСвоюПапку85 и ПодтверждаюЗакрытыйДиалог85 Булево, начально Ложь. Кнопки: ВыгрузитьБезДиалога85, ВыгрузитьДиалогПоУмолчанию85, ВыгрузитьДиалогСКонструктором85, ПроверитьРучнойДиалог85. При каждом новом опыте код сбрасывает подтверждение закрытого диалога; поставьте его заново только после фактического ручного закрытия.
Учебные данные создаются программно: настоящий временный каталог клиента → новая отсутствующая папка OwnFileTransfer85-<новый UUID> → ровно два файла без вложенных путей: own-card.txt и own-total.txt. Кодировка UTF8 без BOM. Первая строка — UUID=<свой UUID>, затем LF и Книга;3;250 либо Сумма=750. Размер измеряется в байтах, не символах. Другой путь, лишний файл, каталог и дубликат отвергаются. Автоматического удаления нет.
Фильтр *.txt в диалоге не защищает от выбора чужого содержимого. Обработчик ДоСвоегоUpload85 перед помещением получает настоящие СсылкаНаФайл и проверяет количество два, точные имена, собственную папку, доступный локальный Файл, содержимое и размер. При отказе он устанавливает ОтказОтПомещенияВсехФайлов=Истина. Платформа после этого не вызывает другие оповещения, поэтому Занято85 сбрасывается прямо здесь.
Параметры обработчиков помещения: завершение — два (ПомещенныеФайлы, К); прогресс — шесть (СсылкаНаФайл, процент файла, отказ файлу, процент всех файлов, отказ всем, К); перед началом — три (массив ссылок, отказ всем, К); ошибка — три (ИнформацияОбОшибке, СтандартнаяОбработка, К). К — структура своего текущего опыта. Параметры отказа изменяются обработчиком. Прогресс — проценты, не байты; число и время вызовов не фиксированы.
ИдентификаторФайла — UUID объекта СсылкаНаФайл, НЕ устойчивый UUID файла на диске и не UUID опыта или формы. Код запоминает настоящий UUID каждого исходного объекта из обработчика начала и сверяет тот же объект до и после Ждать. Результаты и прогресс связываются по проверенным имени и пути; их UUID объекта не предполагается равным UUID исходной ссылки.
Время изменения читается в местном времени и UTC. Каждый результат сравнивается с соответствующим методом связанного Файл; местное время не сравнивается напрямую с UTC. Не меняйте исходные файлы между чтениями. Проверки времени, размера и байтов обнаруживают проверяемые отличия, но НЕ делают две Await операции атомарными.
Пятый параметр помещения — настоящий УникальныйИдентификатор своей формы. Он удерживает данные временного хранилища до закрытия формы; без него данные могут исчезнуть после следующего серверного вызова. СсылкаНаФайл остается на клиенте. Сервер получает только собственные имя и адрес и читает реальные байты из хранилища. После закрытия формы платформа удаляет временные данные, но не исходные файлы.
Проверьте два разных вида отмены помещения: кнопка Отмена в выборе файлов дает в обработчике завершения Неопределено; флажок ОтменитьПередНачалом85 устанавливает отказ перед передачей, поэтому файлов помещено ноль и следующих оповещений нет. Отмена одного файла, частичный массив или ошибка не считаются полной передачей. Автоматического повтора или отката нет; возможные собственные адреса сохраняются, чужие данные не удаляются.
Бездиалоговый вариант получения вызывается с тремя аргументами: оповещение, массив описаний, собственная новая папка. Завершение получает два параметра. До вызова в папке ноль файлов. Описания содержат только свои короткие имена без пути и реальные адреса временного хранилища. Результаты сопоставляются по имени, адресу и полному пути; порядок массива не предполагается. Два файла перечитываются и побайтово проверяются.
Диалогный вариант получения вызывается с двумя аргументами и не имеет оповещения о завершении. ПараметрыДиалогаПолученияФайлов.Каталог — только начальный каталог, НЕ запрет выбрать другое место. Сохраняйте вручную исключительно в показанную новую пустую собственную папку; не подтверждайте перезапись, другой путь или открытие сторонним приложением. Если это неудобно, используйте бездиалоговый путь, а диалог изучайте на своей VM с отменой.
После фактического закрытия диалога самостоятельно поставьте ПодтверждаюЗакрытыйДиалог85 и запустите отдельную проверку. Ноль файлов и ваше подтверждение доказывают лишь отсутствие файлов в этой папке — не автоматическую отмену и не отсутствие файлов в другом месте. Один файл, лишние файлы или неверные байты означают частичный либо неизвестный результат, а не отмену. Не пытайтесь продолжать записи или автоматически откатывать такое состояние.
Формы удерживают один собственный контекст и блокируют параллельные операции. Неизвестный или частичный результат не перекрывается новым опытом. Для второго конструктора помещения откройте новую форму и создайте новую пару. Каждый новый опыт получения создает другую UUID-папку и не перезаписывает старую. Не закрывайте форму во время оповещений или Ждать.
Actualfiles/transfers/UI/1C/DB/network0: здесь только авторство и статические проверки кода по установленной справке. Файлы не передавались, интерфейс не запускался, БД и сеть не изменялись. Сообщения кода — ожидаемый протокол будущего ручного опыта, не доказательство выполнения. Корень проекта и конфигурации только читались; резервные копии и архивы не создавались.
&НаКлиенте
Перем Контекст85;
&НаКлиенте
Процедура СоздатьСвоюПару85(Команда)
Если Занято85 Или Контекст85 <> Неопределено Тогда
ВызватьИсключение "Своя пара уже привязана; для нового независимого опыта откройте новую форму";
КонецЕсли;
UUID = Строка(Новый УникальныйИдентификатор);
К = Новый Структура("UUID,Корень,Фаза,Ссылки,Метки,Адреса", UUID, СоздатьСвоюПапку85(UUID),
"пара", Новый Массив, Новый Соответствие, Новый Массив);
Для Каждого Поле Из СвоиТексты85(UUID) Цикл
Путь = К.Корень + Поле.Ключ;
НовыйФайл = Новый Файл(Путь);
Если НовыйФайл.Существует() Тогда
ВызватьИсключение "Overwrite даже собственного существующего файла не разрешен";
КонецЕсли;
Данные = ПолучитьДвоичныеДанныеИзСтроки(Поле.Значение, КодировкаТекста.UTF8, Ложь);
Данные.Записать(Путь);
КонецЦикла;
ПроверитьСвоиДваФайла85(К);
Контекст85 = К;
ПутьОпыта85 = К.Корень;
Статус85 = "Созданы только2своих UTF8 файла. При выборе укажите их оба именно из " + К.Корень;
КонецПроцедуры
&НаКлиенте
Процедура ПоместитьСОбычнымиПараметрами85(Команда)
Параметры = Новый ПараметрыДиалогаПомещенияФайлов;
Параметры.Заголовок = "Выберите только два файла своей UUID-папки";
Параметры.МножественныйВыбор = Истина;
Параметры.Фильтр = "Свои текстовые файлы (*.txt)|*.txt";
Параметры.ИндексФильтра = 0;
НачатьСвойUpload85(Параметры);
КонецПроцедуры
&НаКлиенте
Процедура ПоместитьСКонструктором85(Команда)
Параметры = Новый ПараметрыДиалогаПомещенияФайлов("Выберите только два файла своей UUID-папки",
Истина, "Свои текстовые файлы (*.txt)|*.txt", 0);
НачатьСвойUpload85(Параметры);
КонецПроцедуры
&НаКлиенте
Процедура НачатьСвойUpload85(Параметры)
ПроверитьСвоегоКлиента85();
Если Занято85 Или Контекст85 = Неопределено Тогда
ВызватьИсключение "Нужна своя пара, не одновременно выполняемая передача";
КонецЕсли;
Если Контекст85.Фаза <> "пара" И Контекст85.Фаза <> "отменено" Тогда
ВызватьИсключение "Уже полученный/частичный опыт не перезапускаем поверх старых адресов";
КонецЕсли;
ПроверитьСвоиДваФайла85(Контекст85);
Если Параметры.Заголовок <> "Выберите только два файла своей UUID-папки"
Или Параметры.МножественныйВыбор <> Истина Или Параметры.ИндексФильтра <> 0
Или Параметры.Фильтр <> "Свои текстовые файлы (*.txt)|*.txt" Тогда
ВызватьИсключение "Нужны действительные параметры своего диалога, индекс фильтра начинается с0";
КонецЕсли;
Контекст85.Фаза = "помещение";
Контекст85.Ссылки = Новый Массив;
Контекст85.Метки = Новый Соответствие;
Контекст85.Адреса = Новый Массив;
Занято85 = Истина;
Завершение = Новый ОписаниеОповещения("СвойUploadЗавершен85", ЭтотОбъект, Контекст85,
"ОшибкаСвоегоUpload85", ЭтотОбъект);
Ход = Новый ОписаниеОповещения("ХодСвоегоUpload85", ЭтотОбъект, Контекст85);
До = Новый ОписаниеОповещения("ДоСвоегоUpload85", ЭтотОбъект, Контекст85);
Статус85 = "Свой диалог начат; успех еще не подтвержден";
Попытка
НачатьПомещениеФайловНаСервер(Завершение, Ход, До, Параметры, УникальныйИдентификатор);
Исключение
Контекст85.Фаза = "ошибка";
Занято85 = Ложь;
Статус85 = "Начало не подтвердилось; auto retry/rollback отсутствуют";
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Функция МеткаСвоейСсылки85(Ссылка, К)
ПроверитьСвойКорень85(К);
Если ТипЗнч(Ссылка) <> Тип("СсылкаНаФайл") Тогда
ВызватьИсключение "Callback должен дать реальную FileRef, не строку пути";
КонецЕсли;
Файл = Ссылка.Файл;
Если Файл = Неопределено Тогда
ВызватьИсключение "Native FileRef.File недоступен; такой контекст не входит в positive workflow";
КонецЕсли;
Тексты = СвоиТексты85(К.UUID);
Текст = Тексты.Получить(Ссылка.Имя);
Если Текст = Неопределено Или Ссылка.Имя <> Файл.Имя Или Ссылка.Расширение <> Файл.Расширение
Или Файл.Расширение <> ".txt" Или Не Файл.Существует() Или Не Файл.ЭтоФайл()
Или НРег(Файл.ПолноеИмя) <> НРег(К.Корень + Ссылка.Имя) Тогда
ВызватьИсключение "До upload допускаем только own flat whitelist/точную UUID-папку";
КонецЕсли;
Ожидание = ПолучитьДвоичныеДанныеИзСтроки(Текст, КодировкаТекста.UTF8, Ложь);
Если Ссылка.Размер() <> Ожидание.Размер() Или Файл.Размер() <> Ожидание.Размер() Тогда
ВызватьИсключение "Размер измеряется вбайтах; не принимаем другие/огромные файлы";
КонецЕсли;
UUIDСсылки = Ссылка.ИдентификаторФайла;
Локальное = Ссылка.ПолучитьВремяИзменения();
Универсальное = Ссылка.ПолучитьУниверсальноеВремяИзменения();
Если ТипЗнч(UUIDСсылки) <> Тип("УникальныйИдентификатор")
Или Локальное <> Файл.ПолучитьВремяИзменения()
Или Универсальное <> Файл.ПолучитьУниверсальноеВремяИзменения() Тогда
ВызватьИсключение "Actual UUID/оба mtime должны соответствовать своему связанному Файл";
КонецЕсли;
ПроверитьСвоиBytes85(Новый ДвоичныеДанные(Файл.ПолноеИмя), Текст);
Возврат Новый Структура("Имя,UUID,Локальное,Универсальное,Размер", Ссылка.Имя, UUIDСсылки,
Локальное, Универсальное, Ожидание.Размер());
КонецФункции
&НаКлиенте
Процедура ДоСвоегоUpload85(ПомещаемыеФайлы, ОтказОтПомещенияВсехФайлов, К) Экспорт
ОтказОтПомещенияВсехФайлов = Истина;
Попытка
Если Контекст85 = Неопределено Или К.UUID <> Контекст85.UUID Или Не Занято85
Или К.Фаза <> "помещение" Или ТипЗнч(ПомещаемыеФайлы) <> Тип("Массив")
Или ПомещаемыеФайлы.Количество() <> 2 Тогда
ВызватьИсключение "Нужна ровно своя текущая пара actual FileRef";
КонецЕсли;
Для Каждого Ссылка Из ПомещаемыеФайлы Цикл
Метка = МеткаСвоейСсылки85(Ссылка, К);
Если К.Метки.Получить(Метка.Имя) <> Неопределено Тогда
ВызватьИсключение "Duplicate own имя не допускается; порядок не используется";
КонецЕсли;
К.Метки.Вставить(Метка.Имя, Метка);
К.Ссылки.Добавить(Ссылка);
КонецЦикла;
Если Не ОтменитьПередНачалом85 Тогда
ОтказОтПомещенияВсехФайлов = Ложь;
Возврат;
КонецЕсли;
К.Фаза = "отменено";
Статус85 = "Явная отмена перед upload:0файлов помещено; native не вызывает следующие оповещения";
Исключение
К.Фаза = "ошибка";
Статус85 = "Чужая/неверная пара отвергнута до помещения; последующие callbacks не ожидаются";
КонецПопытки;
Занято85 = Ложь;
КонецПроцедуры
&НаКлиенте
Процедура ХодСвоегоUpload85(ПомещаемыйФайл, Помещено, ОтказОтПомещенияФайла,
ПомещеноВсего, ОтказОтПомещенияВсехФайлов, К) Экспорт
Попытка
Если Контекст85 = Неопределено Или К.UUID <> Контекст85.UUID Или К.Фаза <> "помещение"
Или ТипЗнч(Помещено) <> Тип("Число") Или ТипЗнч(ПомещеноВсего) <> Тип("Число")
Или Помещено < 0 Или Помещено > 100 Или ПомещеноВсего < 0 Или ПомещеноВсего > 100 Тогда
ВызватьИсключение "Progress — проценты0..100 собственного текущего опыта, не байты";
КонецЕсли;
Метка = МеткаСвоейСсылки85(ПомещаемыйФайл, К);
Если К.Метки.Получить(Метка.Имя) = Неопределено Тогда
ВызватьИсключение "Неизвестный файл вprogress";
КонецЕсли;
Статус85 = Метка.Имя + ": " + Строка(Помещено) + "%; всего " + Строка(ПомещеноВсего) + "%";
Исключение
ОтказОтПомещенияФайла = Истина;
ОтказОтПомещенияВсехФайлов = Истина;
К.Фаза = "ошибка";
Статус85 = "Прогресс неизвестного/измененного файла отменен; частичный результат не является успехом";
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура СвойUploadЗавершен85(ПомещенныеФайлы, К) Экспорт
Попытка
Если Контекст85 = Неопределено Или К.UUID <> Контекст85.UUID Тогда
ВызватьИсключение "Не свой completion-контекст";
КонецЕсли;
Если ПомещенныеФайлы = Неопределено Тогда
К.Фаза = "отменено";
Статус85 = "Native CANCEL: Undefined, успеха/адресов не заявляем";
Иначе
Если К.Фаза <> "помещение" Или ТипЗнч(ПомещенныеФайлы) <> Тип("Массив")
Или ПомещенныеФайлы.Количество() <> 2 Тогда
ВызватьИсключение "Нет полного собственного результата2файла";
КонецЕсли;
Имена = Новый Соответствие;
Для Каждого Описание Из ПомещенныеФайлы Цикл
Если ТипЗнч(Описание) <> Тип("ОписаниеПомещенногоФайла") Или Описание.ПомещениеФайлаОтменено Тогда
ВызватьИсключение "Частичная отмена не равна подтвержденной полной передаче";
КонецЕсли;
Метка = МеткаСвоейСсылки85(Описание.СсылкаНаФайл, К);
Если Имена.Получить(Метка.Имя) <> Неопределено Или К.Метки.Получить(Метка.Имя) = Неопределено
Или ТипЗнч(Описание.Адрес) <> Тип("Строка") Или Не ЭтоАдресВременногоХранилища(Описание.Адрес) Тогда
ВызватьИсключение "Нужны уникальные own имена и реальные адреса временного хранилища";
КонецЕсли;
Имена.Вставить(Метка.Имя, Истина);
К.Адреса.Добавить(Новый Структура("Имя,Адрес", Метка.Имя, Описание.Адрес));
КонецЦикла;
ПроверитьUploadНаСервере85(К.Адреса, К.UUID);
К.Фаза = "помещено";
Статус85 = "Native upload/server bytes подтверждены. Следующая отдельная команда — Await чтение своих FileRef";
КонецЕсли;
Исключение
К.Фаза = "ошибка";
Статус85 = "Upload/readback не подтверждены; собственные возможные адреса сохранены до закрытия формы, rollback нет";
КонецПопытки;
Занято85 = Ложь;
КонецПроцедуры
&НаКлиенте
Процедура ОшибкаСвоегоUpload85(ИнформацияОбОшибке, СтандартнаяОбработка, К) Экспорт
СтандартнаяОбработка = Ложь;
К.Фаза = "ошибка";
Занято85 = Ложь;
Если ТипЗнч(ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке") Тогда
Статус85 = "Native error-callback3args: успех не подтвержден; чужие подробности не выводятся";
Иначе
Статус85 = "Error callback имеет неизвестный тип";
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Асинх Процедура ПрочитатьСвоиFileRef85(Команда)
Если Занято85 Или Контекст85 = Неопределено Тогда
ВызватьИсключение "Нужен свой завершенныйupload, не новая одновременная операция";
КонецЕсли;
К = Контекст85;
Если К.Фаза <> "помещено" Или К.Ссылки.Количество() <> 2 Тогда
ВызватьИсключение "Читать можно только свои2actual FileRef из before-callback";
КонецЕсли;
Занято85 = Истина;
Попытка
ПроверитьСвоегоКлиента85();
Для Каждого Ссылка Из К.Ссылки Цикл
До = МеткаСвоейСсылки85(Ссылка, К);
Была = К.Метки.Получить(До.Имя);
Если Была = Неопределено Или До.UUID <> Была.UUID Или До.Локальное <> Была.Локальное
Или До.Универсальное <> Была.Универсальное Или До.Размер <> Была.Размер Тогда
ВызватьИсключение "Свой FileRef/mtime/size изменился послеbefore; исходные метки не подменяем";
КонецЕсли;
Данные = Ждать Ссылка.ПолучитьКакДвоичныеДанныеАсинх();
Текст = Ждать Ссылка.ПолучитьКакСтрокуАсинх(КодировкаТекста.UTF8);
Тексты = СвоиТексты85(К.UUID);
Ожидание = Тексты.Получить(До.Имя);
ПроверитьСвоиBytes85(Данные, Ожидание);
Если ТипЗнч(Текст) <> Тип("Строка") Или Текст <> Ожидание Тогда
ВызватьИсключение "Await string actual UTF8 должен точно совпасть сown записью";
КонецЕсли;
После = МеткаСвоейСсылки85(Ссылка, К);
Если После.UUID <> До.UUID Или После.Локальное <> До.Локальное
Или После.Универсальное <> До.Универсальное Или После.Размер <> До.Размер Тогда
ВызватьИсключение "Own source изменился во время Await; атомарность чтений не обещается";
КонецЕсли;
КонецЦикла;
ПроверитьUploadНаСервере85(К.Адреса, К.UUID);
К.Фаза = "проверено";
Статус85 = "Свои2native FileRef: readonly UUID/name/extension/file, обаmtime/bytesize, Await UTF8/bytes и serverbytes подтверждены";
Исключение
К.Фаза = "ошибка";
Статус85 = "FileRef Await/mtime/server-readback не подтверждены; original files сохраняются, auto rollback нет";
КонецПопытки;
Занято85 = Ложь;
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ПроверитьUploadНаСервере85(Адреса, UUID)
ПроверитьСвойПустойСтенд();
Тексты = СвоиТексты85(UUID);
Если ТипЗнч(Адреса) <> Тип("Массив") Или Адреса.Количество() <> 2 Тогда
ВызватьИсключение "Нужны именно2own callback-адреса, не произвольное хранилище";
КонецЕсли;
Имена = Новый Соответствие;
Для Каждого Адрес Из Адреса Цикл
Если ТипЗнч(Адрес) <> Тип("Структура") Или Адрес.Количество() <> 2 Тогда
ВызватьИсключение "Передавайте толькоown name/address, FileRef на сервер не передается";
КонецЕсли;
Если Не Адрес.Свойство("Имя", Имя) Или Не Адрес.Свойство("Адрес", Путь)
Или ТипЗнч(Имя) <> Тип("Строка") Или ТипЗнч(Путь) <> Тип("Строка") Тогда
ВызватьИсключение "Own name/address должны быть строками";
КонецЕсли;
Текст = Тексты.Получить(Имя);
Если Текст = Неопределено Или Имена.Получить(Имя) <> Неопределено Или Не ЭтоАдресВременногоХранилища(Путь) Тогда
ВызватьИсключение "Unknown/duplicate own имя или не временный адрес";
КонецЕсли;
ПроверитьСвоиBytes85(ПолучитьИзВременногоХранилища(Путь), Текст);
Имена.Вставить(Имя, Истина);
КонецЦикла;
КонецПроцедуры
&НаКлиентеНаСервереБезКонтекста
Функция СвоиТексты85(UUID)
Если ТипЗнч(UUID) <> Тип("Строка") Тогда
ВызватьИсключение "Нужен UUID своего опыта строкой";
КонецЕсли;
Если Строка(Новый УникальныйИдентификатор(UUID)) <> UUID
Или UUID = "00000000-0000-0000-0000-000000000000" Тогда
ВызватьИсключение "Нужен собственный canonical ненулевой UUID";
КонецЕсли;
Тексты = Новый Соответствие;
Тексты.Вставить("own-card.txt", "UUID=" + UUID + Символы.ПС + "Книга;3;250");
Тексты.Вставить("own-total.txt", "UUID=" + UUID + Символы.ПС + "Сумма=750");
Возврат Тексты;
КонецФункции
&НаКлиентеНаСервереБезКонтекста
Процедура ПроверитьСвоиBytes85(Данные, Текст)
Ожидание = ПолучитьДвоичныеДанныеИзСтроки(Текст, КодировкаТекста.UTF8, Ложь);
Если ТипЗнч(Данные) <> Тип("ДвоичныеДанные") Тогда
ВызватьИсключение "Нужны actual bytes, не текст или ссылка";
КонецЕсли;
Если Данные.Размер() <> Ожидание.Размер()
Или ПолучитьHexСтрокуИзДвоичныхДанных(Данные) <> ПолучитьHexСтрокуИзДвоичныхДанных(Ожидание) Тогда
ВызватьИсключение "Файл обязан содержать ровно свои concrete UTF8 bytes безBOM";
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьСвоегоКлиента85()
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Система = Новый СистемнаяИнформация;
Если Система.ТипПлатформы <> ТипПлатформы.Windows_x86_64 Тогда
ВызватьИсключение "Нужен свой толстый управляемый Windowsx64 клиент8.5.1.1343";
КонецЕсли;
Если Не ПодтверждаюСвойСтенд85 Тогда
ВызватьИсключение "Подтвердите только новый пустой собственный стенд";
КонецЕсли;
ПроверитьНаСервере85();
#Иначе
ВызватьИсключение "Thin/web/mobile positive path здесь не заявлен; native FileRef.File может быть Undefined";
#КонецЕсли
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ПроверитьНаСервере85()
ПроверитьСвойПустойСтенд();
КонецПроцедуры
&НаКлиенте
Функция СоздатьСвоюПапку85(UUID)
ПроверитьСвоегоКлиента85();
СвоиТексты85(UUID);
База = КаталогВременныхФайлов();
Если Сред(База, 2, 2) <> ":\" Или Лев(База, 2) = "\\" Тогда
ВызватьИсключение "Только actual local Windows native temp, не UNC/произвольный input";
КонецЕсли;
Если Прав(База, 1) <> "\" Тогда
База = База + "\";
КонецЕсли;
Папка = Новый Файл(База);
Если Не Папка.Существует() Или Не Папка.ЭтоКаталог() Тогда
ВызватьИсключение "Native temp должен существовать";
КонецЕсли;
Корень = База + "OwnFileTransfer85-" + UUID + "\";
Свежая = Новый Файл(Корень);
Если Свежая.Существует() Тогда
ВызватьИсключение "Своя UUID-папка уже существует; overwrite запрещен";
КонецЕсли;
СоздатьКаталог(Корень);
Если НайтиФайлы(Корень, "*", Ложь).Количество() <> 0 Тогда
ВызватьИсключение "Нужна свежая пустая собственная папка";
КонецЕсли;
Возврат Корень;
КонецФункции
&НаКлиенте
Процедура ПроверитьСвойКорень85(К)
СвоиТексты85(К.UUID);
База = КаталогВременныхФайлов();
Если Прав(База, 1) <> "\" Тогда
База = База + "\";
КонецЕсли;
Если К.Корень <> База + "OwnFileTransfer85-" + К.UUID + "\" Тогда
ВызватьИсключение "Не свой actual native-temp UUID root";
КонецЕсли;
Папка = Новый Файл(К.Корень);
Если Не Папка.Существует() Или Не Папка.ЭтоКаталог() Тогда
ВызватьИсключение "Своя созданная папка должна существовать";
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьСвоиДваФайла85(К)
ПроверитьСвойКорень85(К);
Тексты = СвоиТексты85(К.UUID);
Файлы = НайтиФайлы(К.Корень, "*", Ложь);
Если Файлы.Количество() <> 2 Тогда
ВызватьИсключение "Нужны ровно2своих файла, без дополнительных/частичных результатов";
КонецЕсли;
Для Каждого Файл Из Файлы Цикл
Текст = Тексты.Получить(Файл.Имя);
Если Текст = Неопределено Или Не Файл.ЭтоФайл()
Или НРег(Файл.ПолноеИмя) <> НРег(К.Корень + Файл.Имя) Тогда
ВызватьИсключение "Нужен точный whitelist собственных flat имен, не каталог/другой путь";
КонецЕсли;
Ожидание = ПолучитьДвоичныеДанныеИзСтроки(Текст, КодировкаТекста.UTF8, Ложь);
Если Файл.Размер() <> Ожидание.Размер() Тогда
ВызватьИсключение "Сначала exact маленький размер own fixture, потом чтениеbytes; другие/огромные файлы не загружаем";
КонецЕсли;
ПроверитьСвоиBytes85(Новый ДвоичныеДанные(Файл.ПолноеИмя), Текст);
КонецЦикла;
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ПроверитьСвойПустойСтенд()
Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
КонецЕсли;
Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
КонецЕсли;
Источники = Новый Массив;
Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
Для Каждого Источник Из Источники Цикл
Расширения = РасширенияКонфигурации.Получить(, Источник);
Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
ВызватьИсключение "Native список расширений должен иметь тип Массив";
КонецЕсли;
Если Расширения.Количество() <> 0 Тогда
ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
КонецЕсли;
КонецЦикла;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
КонецЕсли;
КонецПроцедурыРазбор по шагам
СоздатьСвоюПару85 создает новую папку и два файла с заданным содержимым, затем проверяет байты. Скопируйте показанный путь: в диалоге выбирайте только эту пару.
Первый вариант создает ПараметрыДиалогаПомещенияФайлов по умолчанию и задает четыре свойства. Второй передает те же значения конструктору. ИндексФильтра начинается с нуля, поэтому указан 0, не 1.
Перед началом передачи обработчик получает две настоящие СсылкаНаФайл. Проверяются точные имена, путь, содержимое и размер. Для последующего чтения сохраняются сами ссылки и пять полей: имя, UUID объекта, местное время, UTC и размер.
Завершение отдельно обрабатывает Неопределено при отмене. Для успешного массива нужны два разных известных имени, отсутствие отмены каждого файла и настоящие адреса временного хранилища. Сервер перечитывает и проверяет содержимое, не только наличие адресов.
ПрочитатьСвоиFileRef85 — отдельная асинхронная команда. Ждать получает из каждой исходной ссылки ДвоичныеДанные и строку UTF8. Содержимое должно точно совпасть с учебными записями; UUID объекта, размер и оба времени изменения до и после чтения должны остаться прежними.
Для второго конструктора повторите самостоятельный опыт в новой форме. Отрицательные проверки: отмените диалог; включите отмену перед началом; выберите один или чужой файл; измените собственное содержимое перед чтением. Частичный и неизвестный результат не объявляются успехом и не откатываются автоматически.
Исходные файлы остаются для ручного контроля. Закрытие формы освобождает только связанные временные данные. Архивирование и удаление файлов в уроке отсутствуют.
Как проверить результат
Проверены два собственных коротких имени, UUID, точные байты и размер; произвольный *.txt или первый элемент массива не принимаются.
Конструкторы, свойства и методы реально используются. Обработчики с 2, 6, 3 параметрами и обработчик ошибки с 3 параметрами согласованы с установленной справкой 8.5.1.1343.
Свойства ссылок и результатов только для чтения не присваиваются. Недоступный СсылкаНаФайл.Файл не заменяется выдуманным локальным файлом.
Отмена, частичный результат, неизвестное состояние и ошибка различаются. Нет автоматического повтора, отката, обещания атомарности или успеха без чтения результата.
Интерфейс, файловая передача и 1С здесь не запускались. Проверки статические; подготовка относится только к вашему будущему собственному опыту.
Ожидаемый результат
Ожидаемый ручной результат: две собственные записи UTF8 о книге, количестве 3, цене 250 и сумме 750 передаются без изменений. Настоящие ссылки, описания и прочитанное содержимое проверяются. Отмена и частичный результат не объявляются успехом. Фактический запуск не выполнялся.
На что обратить внимание
Фильтр помещения не ограничивает содержимое. Имена, путь и байты проверяются перед передачей. После отказа перед началом других оповещений не будет, поэтому признак занятости сбрасывается там.
Диалогное получение не имеет оповещения о завершении. Начальный каталог — не граница безопасности, а ручное подтверждение закрытия — не флаг платформы. Для контролируемого назначения выбирайте бездиалоговый маршрут.
Проверки времени, размера и два Ждать не атомарны. Частичные или неизвестные результаты нельзя перекрывать повторной записью или слепо откатывать. Код ничего не удаляет.
UUID ссылки идентифицирует объект, не физический файл. В веб-клиенте связанный Файл может быть недоступен; такой вариант честно отвергается и не объявляется рабочим примером.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.