СсылкаНаФайл

Типы · FileRef

Представляет собой указатель файла на диске.

Полное описание, параметры и ограничения

СсылкаНаФайл (FileRef)

СсылкаНаФайл (FileRef)

Доступен, начиная с версии 8.3.13.

Свойства:
ИдентификаторФайла (FileID)
Имя (Name)
Расширение (Extension)
Файл (File)

Методы:
ПолучитьВремяИзменения (GetModificationTime)
ПолучитьКакДвоичныеДанныеАсинх (GetAsBinaryDataAsync)
ПолучитьКакСтрокуАсинх (GetAsStringAsync)
ПолучитьУниверсальноеВремяИзменения (GetModificationUniversalTime)
Размер (Size)

Описание:

Представляет собой указатель файла на диске.

Доступность:

Тонкий клиент, веб-клиент, толстый клиент.

Использование в версии:

Доступен, начиная с версии 8.3.13.

Описание изменено в версии 8.3.24.

Методическая информация

Практические примеры

Собственная UTF8-пара: ссылки на файлы, помещение с оповещениями и чтение через Ждать

Полный учебный маршрут с собственными данными и настоящими объектами платформы. Две записи UTF8, новые UUID, точные параметры оповещений, сопоставление по имени и независимое чтение результата. Отмена и ограничения выбора папки объясняются отдельно.

Где и как запускать

Полный модуль своей управляемой формы новой пустой файловой ИБ 8.5.1.1343. Толстый управляемый Windows x64 клиент; сервер только проверяет пустой стенд и временные данные. Фактические UI/files/1C/network операции: 0.

Подготовка

  1. Создайте новую собственную пустую файловую информационную базу на платформе 8.5.1.1343. Имя корня конфигурации — УчебныеСсылкиИПередачаФайлов85. Русский встроенный язык, управляемое приложение, совместимость «Не использовать». Не берите рабочую базу или чужие файлы. В конфигурации нет справочников, документов, регистров, планов, задач, подписок, заданий, общих реквизитов, внешних источников и расширений.

  2. Запускайте только толстый управляемый клиент Windows x64 под отдельным учебным профилем Windows. Справка разрешает многие эти API также в тонком, веб- и мобильном клиентах, но там отличаются доступ к файлам и диалоги. Эти варианты здесь не заявляются проверенными. Расширения браузера и внешние сервисы для выбранного маршрута не нужны.

  3. Создайте внешнюю обработку OwnFileTransfer85 и одну управляемую форму. Реквизиты: ПодтверждаюСвойСтенд85 — Булево, начально Ложь; Занято85 — Булево, начально Ложь, ТолькоПросмотр; ПутьОпыта85 — Строка неограниченной длины, ТолькоПросмотр; Статус85 — такая же Строка, многострочная, ТолькоПросмотр. Вставьте целиком модуль выбранной карточки; два модуля не объединяйте.

  4. Для помещения файлов на сервер добавьте реквизит ОтменитьПередНачалом85 — Булево, начально Ложь. Создайте команды и кнопки: СоздатьСвоюПару85, ПоместитьСОбычнымиПараметрами85, ПоместитьСКонструктором85, ПрочитатьСвоиFileRef85. Параметр Команда передает сама кнопка. Оповещения связывают экспортные обработчики с событиями завершения, прогресса, начала и ошибки передачи.

  5. Download форма дополнительно: ПодтверждаюТолькоСвоюПапку85 и ПодтверждаюЗакрытыйДиалог85 Булево, начально Ложь. Кнопки: ВыгрузитьБезДиалога85, ВыгрузитьДиалогПоУмолчанию85, ВыгрузитьДиалогСКонструктором85, ПроверитьРучнойДиалог85. При каждом новом опыте код сбрасывает подтверждение закрытого диалога; поставьте его заново только после фактического ручного закрытия.

  6. Учебные данные создаются программно: настоящий временный каталог клиента → новая отсутствующая папка OwnFileTransfer85-<новый UUID> → ровно два файла без вложенных путей: own-card.txt и own-total.txt. Кодировка UTF8 без BOM. Первая строка — UUID=<свой UUID>, затем LF и Книга;3;250 либо Сумма=750. Размер измеряется в байтах, не символах. Другой путь, лишний файл, каталог и дубликат отвергаются. Автоматического удаления нет.

  7. Фильтр *.txt в диалоге не защищает от выбора чужого содержимого. Обработчик ДоСвоегоUpload85 перед помещением получает настоящие СсылкаНаФайл и проверяет количество два, точные имена, собственную папку, доступный локальный Файл, содержимое и размер. При отказе он устанавливает ОтказОтПомещенияВсехФайлов=Истина. Платформа после этого не вызывает другие оповещения, поэтому Занято85 сбрасывается прямо здесь.

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

  9. ИдентификаторФайла — UUID объекта СсылкаНаФайл, НЕ устойчивый UUID файла на диске и не UUID опыта или формы. Код запоминает настоящий UUID каждого исходного объекта из обработчика начала и сверяет тот же объект до и после Ждать. Результаты и прогресс связываются по проверенным имени и пути; их UUID объекта не предполагается равным UUID исходной ссылки.

  10. Время изменения читается в местном времени и UTC. Каждый результат сравнивается с соответствующим методом связанного Файл; местное время не сравнивается напрямую с UTC. Не меняйте исходные файлы между чтениями. Проверки времени, размера и байтов обнаруживают проверяемые отличия, но НЕ делают две Await операции атомарными.

  11. Пятый параметр помещения — настоящий УникальныйИдентификатор своей формы. Он удерживает данные временного хранилища до закрытия формы; без него данные могут исчезнуть после следующего серверного вызова. СсылкаНаФайл остается на клиенте. Сервер получает только собственные имя и адрес и читает реальные байты из хранилища. После закрытия формы платформа удаляет временные данные, но не исходные файлы.

  12. Проверьте два разных вида отмены помещения: кнопка Отмена в выборе файлов дает в обработчике завершения Неопределено; флажок ОтменитьПередНачалом85 устанавливает отказ перед передачей, поэтому файлов помещено ноль и следующих оповещений нет. Отмена одного файла, частичный массив или ошибка не считаются полной передачей. Автоматического повтора или отката нет; возможные собственные адреса сохраняются, чужие данные не удаляются.

  13. Бездиалоговый вариант получения вызывается с тремя аргументами: оповещение, массив описаний, собственная новая папка. Завершение получает два параметра. До вызова в папке ноль файлов. Описания содержат только свои короткие имена без пути и реальные адреса временного хранилища. Результаты сопоставляются по имени, адресу и полному пути; порядок массива не предполагается. Два файла перечитываются и побайтово проверяются.

  14. Диалогный вариант получения вызывается с двумя аргументами и не имеет оповещения о завершении. ПараметрыДиалогаПолученияФайлов.Каталог — только начальный каталог, НЕ запрет выбрать другое место. Сохраняйте вручную исключительно в показанную новую пустую собственную папку; не подтверждайте перезапись, другой путь или открытие сторонним приложением. Если это неудобно, используйте бездиалоговый путь, а диалог изучайте на своей VM с отменой.

  15. После фактического закрытия диалога самостоятельно поставьте ПодтверждаюЗакрытыйДиалог85 и запустите отдельную проверку. Ноль файлов и ваше подтверждение доказывают лишь отсутствие файлов в этой папке — не автоматическую отмену и не отсутствие файлов в другом месте. Один файл, лишние файлы или неверные байты означают частичный либо неизвестный результат, а не отмену. Не пытайтесь продолжать записи или автоматически откатывать такое состояние.

  16. Формы удерживают один собственный контекст и блокируют параллельные операции. Неизвестный или частичный результат не перекрывается новым опытом. Для второго конструктора помещения откройте новую форму и создайте новую пару. Каждый новый опыт получения создает другую UUID-папку и не перезаписывает старую. Не закрывайте форму во время оповещений или Ждать.

  17. 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 Тогда
            ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
        КонецЕсли;
    КонецЦикла;
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
    КонецЕсли;
КонецПроцедуры

Разбор по шагам

  1. СоздатьСвоюПару85 создает новую папку и два файла с заданным содержимым, затем проверяет байты. Скопируйте показанный путь: в диалоге выбирайте только эту пару.

  2. Первый вариант создает ПараметрыДиалогаПомещенияФайлов по умолчанию и задает четыре свойства. Второй передает те же значения конструктору. ИндексФильтра начинается с нуля, поэтому указан 0, не 1.

  3. Перед началом передачи обработчик получает две настоящие СсылкаНаФайл. Проверяются точные имена, путь, содержимое и размер. Для последующего чтения сохраняются сами ссылки и пять полей: имя, UUID объекта, местное время, UTC и размер.

  4. Завершение отдельно обрабатывает Неопределено при отмене. Для успешного массива нужны два разных известных имени, отсутствие отмены каждого файла и настоящие адреса временного хранилища. Сервер перечитывает и проверяет содержимое, не только наличие адресов.

  5. ПрочитатьСвоиFileRef85 — отдельная асинхронная команда. Ждать получает из каждой исходной ссылки ДвоичныеДанные и строку UTF8. Содержимое должно точно совпасть с учебными записями; UUID объекта, размер и оба времени изменения до и после чтения должны остаться прежними.

  6. Для второго конструктора повторите самостоятельный опыт в новой форме. Отрицательные проверки: отмените диалог; включите отмену перед началом; выберите один или чужой файл; измените собственное содержимое перед чтением. Частичный и неизвестный результат не объявляются успехом и не откатываются автоматически.

  7. Исходные файлы остаются для ручного контроля. Закрытие формы освобождает только связанные временные данные. Архивирование и удаление файлов в уроке отсутствуют.

Как проверить результат

  1. Проверены два собственных коротких имени, UUID, точные байты и размер; произвольный *.txt или первый элемент массива не принимаются.

  2. Конструкторы, свойства и методы реально используются. Обработчики с 2, 6, 3 параметрами и обработчик ошибки с 3 параметрами согласованы с установленной справкой 8.5.1.1343.

  3. Свойства ссылок и результатов только для чтения не присваиваются. Недоступный СсылкаНаФайл.Файл не заменяется выдуманным локальным файлом.

  4. Отмена, частичный результат, неизвестное состояние и ошибка различаются. Нет автоматического повтора, отката, обещания атомарности или успеха без чтения результата.

  5. Интерфейс, файловая передача и 1С здесь не запускались. Проверки статические; подготовка относится только к вашему будущему собственному опыту.

Ожидаемый результат

Ожидаемый ручной результат: две собственные записи UTF8 о книге, количестве 3, цене 250 и сумме 750 передаются без изменений. Настоящие ссылки, описания и прочитанное содержимое проверяются. Отмена и частичный результат не объявляются успехом. Фактический запуск не выполнялся.

На что обратить внимание

  1. Фильтр помещения не ограничивает содержимое. Имена, путь и байты проверяются перед передачей. После отказа перед началом других оповещений не будет, поэтому признак занятости сбрасывается там.

  2. Диалогное получение не имеет оповещения о завершении. Начальный каталог — не граница безопасности, а ручное подтверждение закрытия — не флаг платформы. Для контролируемого назначения выбирайте бездиалоговый маршрут.

  3. Проверки времени, размера и два Ждать не атомарны. Частичные или неизвестные результаты нельзя перекрывать повторной записью или слепо откатывать. Код ничего не удаляет.

  4. UUID ссылки идентифицирует объект, не физический файл. В веб-клиенте связанный Файл может быть недоступен; такой вариант честно отвергается и не объявляется рабочим примером.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.