Получает значение разделителя пути, используемого в операционной системе, в которой работает рабочий процесс сервера.
Синтаксис
ПолучитьРазделительПутиСервера()Полное описание, параметры и ограничения
Глобальный контекст.ПолучитьРазделительПутиСервера (Global context.GetServerPathSeparator)
Глобальный контекст (Global context)
ПолучитьРазделительПутиСервера (GetServerPathSeparator)
Доступен, начиная с версии 8.3.3.
Синтаксис:
ПолучитьРазделительПутиСервера()
Возвращаемое значение:
Тип: Строка.
Разделитель пути возвращается в виде строки. Например: "\".
Описание:
Получает значение разделителя пути, используемого в операционной системе, в которой работает рабочий процесс сервера.
Доступность:
Сервер, толстый клиент, мобильное приложение (сервер), мобильный автономный сервер.
Примечание:
Вызывается исключение, если код выполняется на клиенте в клиент-серверном варианте.
Использование в версии:
Доступен, начиная с версии 8.3.3.
Методическая информация
Практические примеры
Найти свои файлы на клиенте и сервере правильными масками и разделителями
Полный модуль формы: создаёт два независимых коротких файла на соответствующих сторонах, использует фактические маски ОС для поиска, проверяет байты и удаляет только свой опыт.
Где и как запускать
Полный модуль управляемой формы УчебныеФайловыеКонтексты85: толстый клиент Windows, НаСервереБезКонтекста и чистая проверка НаКлиентеНаСервереБезКонтекста.
Подготовка
Создайте новую пустую конфигурацию УчебныеФайловыеКонтексты85 на платформе 8.5.1.1343, управляемое приложение. Рабочие базы и реальные файловые данные не подходят.
Клиент — толстый клиент Windows. Для содержательного сравнения разных ОС можно позже вручную использовать изолированный сервер 1С Linux; это не обязательная настройка и сейчас сервер не разворачивается.
Обработки → ОпытКонтекстов85 → управляемая форма Форма. Весь приведённый код помещается в один модуль формы: директивы определяют, на какой стороне выполняется каждая процедура.
Реквизиты формы: ПодтверждаюСвоиФайлы85 и Занято85 типа Булево; ПутьСвоегоКаталога85 и Итог85 типа Строка неограниченной длины. Исходно флажки Ложь.
Согласие показывайте флажком для ввода, занятость, путь и итог — только для просмотра. Никакого пользовательского поля для серверного пути нет.
Создайте команду СравнитьСвоиФайловыеКонтексты85 и её действие, выведите кнопку. ПередЗакрытием назначьте одноимённому событию с четырьмя параметрами из полного модуля.
Вставьте код, нажмите F7 и обновите только стенд. runtimeVerifiedScenarios=0: 1С, серверный вызов, создание файлов, поиск и очистка здесь не выполнялись.
Администратор отдельно проверяет локальный временный каталог клиента и временный каталог рабочего процесса сервера. Нужны права создания/чтения/удаления и отсутствие чужих писателей и подмены файлов ссылками.
На сервере путь создаёт сам неконтекстный серверный метод через ПолучитьИмяВременногоФайла. Путь клиента туда вообще не передаётся и не становится серверным источником.
Клиентский опыт содержит source.txt с ABC-85, серверный — server-source.txt с SERVER-85. Это соответственно шесть и девять байт UTF-8; секретные и рабочие файлы не используются.
Клиентская папка имеет расширение guidefiles, серверная — guidectx. Существующий объект по сгенерированному имени отклоняется; имена не означают атомарного резервирования.
Подтвердите только собственный опыт и вручную запустите команду. Дождитесь снятия Занято85, не меняйте файлы извне и не прерывайте клиент/сервер во время опыта.
На обеих сторонах поиск нерекурсивный. Каждая нативная маска используется реально в НайтиФайлы, а не просто печатается в сообщении.
Не ожидайте разных результатов масок на одинаковой ОС и не требуйте равенства масок на разных ОС. Проверяется обнаружение собственного файла, а не заранее заданная строка *.* или определённый разделитель.
Серверная очистка завершается до возврата отчёта. Клиентская выполняется независимо после результата или ошибки серверного вызова; никакие посторонние файлы и непустые каталоги не удаляются.
&НаКлиенте
Процедура СравнитьСвоиФайловыеКонтексты85(Команда)
ПроверитьСвойСтенд85();
Занято85 = Истина;
К = Неопределено;
ОшибкаОпыта = "";
Отчет = "";
Попытка
К = СоздатьСвойКонтекст85();
СоздатьКаталог(К.Каталог);
К.КаталогСоздан = Истина;
ЗаписатьСвойИсходник85(К);
МаскаКлиента = ПолучитьМаскуВсеФайлыКлиента();
МаскаТекущаяКлиента = ПолучитьМаскуВсеФайлы();
ПроверитьОдноСвоеСовпадение85(НайтиФайлы(К.Каталог, МаскаКлиента, Ложь), К.Исходник);
ПроверитьОдноСвоеСовпадение85(НайтиФайлы(К.Каталог, МаскаТекущаяКлиента, Ложь), К.Исходник);
ПрочитанныеБайты = Новый ДвоичныеДанные(К.Исходник);
Если Base64Строка(ПрочитанныеБайты) <> Base64Строка(К.ОжидаемыеБайты) Тогда
ВызватьИсключение "Собственный файл клиента отличается от ABC-85";
КонецЕсли;
Сервер = ПроверитьСвойСерверныйКаталог85(ПодтверждаюСвоиФайлы85);
Отчет = "Клиент: " + К.Каталог + "; разделитель " + К.Разделитель
+ "; маска клиента " + МаскаКлиента + "; текущая маска " + МаскаТекущаяКлиента
+ ". Сервер: " + Сервер.Каталог + "; разделитель " + Сервер.Разделитель
+ "; маска сервера " + Сервер.МаскаСервера + "; текущая маска " + Сервер.МаскаТекущая
+ ". На каждой стороне найден и прочитан только свой файл; серверный опыт очищен.";
Исключение
ОшибкаОпыта = ОписаниеОшибки();
КонецПопытки;
ОшибкаОчистки = ОчиститьТолькоСвойОпыт85(К);
Занято85 = Ложь;
Если ОшибкаОпыта <> "" Или ОшибкаОчистки <> "" Тогда
Итог85 = ОшибкаОпыта + " " + ОшибкаОчистки;
ВызватьИсключение Итог85;
КонецЕсли;
Итог85 = Отчет + " Клиентский опыт также очищен.";
КонецПроцедуры
&НаКлиентеНаСервереБезКонтекста
Процедура ПроверитьОдноСвоеСовпадение85(Найденные, ОжидаемыйПуть)
Если ТипЗнч(Найденные) <> Тип("Массив") Или Найденные.Количество() <> 1 Тогда
ВызватьИсключение "Маска должна найти ровно один собственный учебный файл";
КонецЕсли;
Для Каждого Найденный Из Найденные Цикл
Если Найденный.ПолноеИмя <> ОжидаемыйПуть Или Найденный.ЭтоКаталог() Тогда
ВызватьИсключение "Поиск обнаружил не свой файл; неизвестный объект не удаляется";
КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПроверитьСвойСерверныйКаталог85(Согласие)
Если Не Согласие Тогда
ВызватьИсключение "Только свой пустой стенд УчебныеФайловыеКонтексты85 с согласием";
КонецЕсли;
Разделитель = ПолучитьРазделительПутиСервера();
МаскаСервера = ПолучитьМаскуВсеФайлыСервера();
МаскаТекущая = ПолучитьМаскуВсеФайлы();
Каталог = ПолучитьИмяВременногоФайла("guidectx");
ФайлКаталога = Новый Файл(Каталог);
Если ФайлКаталога.Существует() Тогда
ВызватьИсключение "Серверное имя уже занято; объект не считается своим";
КонецЕсли;
Путь = Каталог + Разделитель + "server-source.txt";
КаталогСоздан = Ложь;
ОшибкаОпыта = "";
Попытка
СоздатьКаталог(Каталог);
КаталогСоздан = Истина;
СвойФайл = Новый Файл(Путь);
Если СвойФайл.Существует() Тогда
ВызватьИсключение "Серверный источник уже занят; перезапись запрещена";
КонецЕсли;
ОжидаемыеБайты = ПолучитьДвоичныеДанныеИзСтроки("SERVER-85", КодировкаТекста.UTF8);
ОжидаемыеБайты.Записать(Путь);
ПроверитьОдноСвоеСовпадение85(НайтиФайлы(Каталог, МаскаСервера, Ложь), Путь);
ПроверитьОдноСвоеСовпадение85(НайтиФайлы(Каталог, МаскаТекущая, Ложь), Путь);
ПрочитанныеБайты = Новый ДвоичныеДанные(Путь);
Если Base64Строка(ПрочитанныеБайты) <> Base64Строка(ОжидаемыеБайты) Тогда
ВызватьИсключение "Серверный файл отличается от SERVER-85";
КонецЕсли;
Исключение
ОшибкаОпыта = ОписаниеОшибки();
КонецПопытки;
ОшибкаОчистки = ОчиститьСвойСерверныйКаталог85(Каталог, Разделитель, Путь, КаталогСоздан);
Если ОшибкаОпыта <> "" Или ОшибкаОчистки <> "" Тогда
ВызватьИсключение ОшибкаОпыта + " " + ОшибкаОчистки;
КонецЕсли;
Возврат Новый Структура("Каталог,Разделитель,МаскаСервера,МаскаТекущая", Каталог, Разделитель, МаскаСервера, МаскаТекущая);
КонецФункции
&НаСервереБезКонтекста
Функция ОчиститьСвойСерверныйКаталог85(Каталог, Разделитель, Путь, КаталогСоздан)
Если Не КаталогСоздан Тогда
Возврат "Создание собственного серверного каталога не подтверждено; очистка не начата";
КонецЕсли;
Если Прав(Каталог, 9) <> ".guidectx" Или Путь <> Каталог + Разделитель + "server-source.txt" Тогда
Возврат "Не совпали границы собственного серверного опыта; очистка не начата";
КонецЕсли;
ОшибкаОчистки = "";
Попытка
СвойФайл = Новый Файл(Путь);
Если СвойФайл.Существует() Тогда
Если СвойФайл.ЭтоКаталог() Тогда
ВызватьИсключение "На месте своего серверного файла каталог; его не удаляем";
КонецЕсли;
УдалитьФайлы(Путь);
КонецЕсли;
Если СвойФайл.Существует() Тогда
ВызватьИсключение "Свой серверный файл остался после удаления";
КонецЕсли;
Исключение
ОшибкаОчистки = ОшибкаОчистки + " " + ОписаниеОшибки();
КонецПопытки;
Попытка
СвойКаталог = Новый Файл(Каталог);
Если СвойКаталог.Существует() Тогда
Остаток = НайтиФайлы(Каталог, "*", Ложь);
Если Остаток.Количество() <> 0 Тогда
ВызватьИсключение "Серверный каталог не пуст; чужие объекты не удаляем";
КонецЕсли;
УдалитьФайлы(Каталог);
КонецЕсли;
Если СвойКаталог.Существует() Тогда
ВызватьИсключение "Свой пустой серверный каталог остался после удаления";
КонецЕсли;
Исключение
ОшибкаОчистки = ОшибкаОчистки + " " + ОписаниеОшибки();
КонецПопытки;
Возврат ОшибкаОчистки;
КонецФункции
&НаКлиенте
Процедура ПроверитьСвойСтенд85()
Если Не ПодтверждаюСвоиФайлы85 Тогда
ВызватьИсключение "Только собственный новый стенд УчебныеФайловыеКонтексты85 с согласием";
КонецЕсли;
Если Занято85 Тогда
ВызватьИсключение "Дождитесь завершения текущего собственного опыта";
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Функция СоздатьСвойКонтекст85()
Разделитель = ПолучитьРазделительПути();
Каталог = ПолучитьИмяВременногоФайла("guidefiles");
ФайлКаталога = Новый Файл(Каталог);
Если ФайлКаталога.Существует() Тогда
ВызватьИсключение "Уникальное имя уже занято; найденный объект не считается своим";
КонецЕсли;
К = Новый Структура;
К.Вставить("Каталог", Каталог);
К.Вставить("Разделитель", Разделитель);
К.Вставить("КаталогСоздан", Ложь);
К.Вставить("Исходник", Каталог + Разделитель + "source.txt");
К.Вставить("Копия", Каталог + Разделитель + "copy.txt");
К.Вставить("Перемещенный", Каталог + Разделитель + "moved.txt");
К.Вставить("ОжидаемыеБайты", ПолучитьДвоичныеДанныеИзСтроки("ABC-85", КодировкаТекста.UTF8));
ПутьСвоегоКаталога85 = Каталог;
Возврат К;
КонецФункции
&НаКлиенте
Процедура ПроверитьСвоюОбласть85(К)
Если К.Каталог <> ПутьСвоегоКаталога85 Или Прав(К.Каталог, 11) <> ".guidefiles" Тогда
ВызватьИсключение "Не совпал собственный сгенерированный каталог этого опыта";
КонецЕсли;
Если К.Исходник <> К.Каталог + К.Разделитель + "source.txt"
Или К.Копия <> К.Каталог + К.Разделитель + "copy.txt"
Или К.Перемещенный <> К.Каталог + К.Разделитель + "moved.txt" Тогда
ВызватьИсключение "Изменились границы собственной файловой области";
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ЗаписатьСвойИсходник85(К)
ПроверитьСвоюОбласть85(К);
ФайлКаталога = Новый Файл(К.Каталог);
Если Не К.КаталогСоздан Или Не ФайлКаталога.Существует() Или Не ФайлКаталога.ЭтоКаталог() Тогда
ВызватьИсключение "Создание своего каталога ещё не подтверждено";
КонецЕсли;
ФайлИсходника = Новый Файл(К.Исходник);
Если ФайлИсходника.Существует() Тогда
ВызватьИсключение "Свой источник не должен перезаписывать существующий файл";
КонецЕсли;
К.ОжидаемыеБайты.Записать(К.Исходник);
КонецПроцедуры
&НаКлиенте
Функция ОчиститьТолькоСвойОпыт85(К)
Если К = Неопределено Тогда
Возврат "";
КонецЕсли;
ОшибкаОчистки = "";
Попытка
ПроверитьСвоюОбласть85(К);
Исключение
Возврат "Границы опыта не подтвердились; очистка не начата: " + ОписаниеОшибки();
КонецПопытки;
Если Не К.КаталогСоздан Тогда
Возврат "Создание каталога не подтвердилось; автоматическая очистка не выполнялась";
КонецЕсли;
Имена = Новый Массив;
Имена.Добавить(К.Исходник);
Имена.Добавить(К.Копия);
Имена.Добавить(К.Перемещенный);
Для Каждого Имя Из Имена Цикл
Попытка
СвойФайл = Новый Файл(Имя);
Если СвойФайл.Существует() Тогда
Если СвойФайл.ЭтоКаталог() Тогда
ВызватьИсключение "На месте своего файла обнаружен каталог; его не удаляем";
КонецЕсли;
УдалитьФайлы(Имя);
КонецЕсли;
Если СвойФайл.Существует() Тогда
ВызватьИсключение "Свой файл остался после удаления";
КонецЕсли;
Исключение
ОшибкаОчистки = ОшибкаОчистки + " " + ОписаниеОшибки();
КонецПопытки;
КонецЦикла;
Попытка
СвойКаталог = Новый Файл(К.Каталог);
Если СвойКаталог.Существует() Тогда
Остаток = НайтиФайлы(К.Каталог, "*", Ложь);
Если Остаток.Количество() <> 0 Тогда
ВызватьИсключение "Каталог не пуст; неизвестные объекты не удаляем";
КонецЕсли;
УдалитьФайлы(К.Каталог);
КонецЕсли;
Если СвойКаталог.Существует() Тогда
ВызватьИсключение "Свой пустой каталог остался после удаления";
КонецЕсли;
Исключение
ОшибкаОчистки = ОшибкаОчистки + " " + ОписаниеОшибки();
КонецПопытки;
Возврат ОшибкаОчистки;
КонецФункции
&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
Если Занято85 Тогда
Отказ = Истина;
ТекстПредупреждения = "Дождитесь завершения собственного файлового опыта";
КонецЕсли;
КонецПроцедурыРазбор по шагам
Клиентский обработчик проверяет свой стенд, версию и согласие; флаг занятости исключает второй запуск. Создаётся только source.txt в новом собственном клиентском каталоге.
ПолучитьМаскуВсеФайлыКлиента возвращает правило ОС клиента, ПолучитьМаскуВсеФайлы — текущего контекста. Обе полученные строки используются в отдельном поиске собственного каталога.
Общий чистый проверочный метод компилируется для клиента и сервера. Он не переносит файловые операции между сторонами: проверяет только один реальный найденный Файл, полный путь и отсутствие каталога.
На клиенте читаются реальные байты source.txt и сравниваются с ABC-85. Затем неконтекстный серверный вызов получает только согласие, а не клиентский путь.
На сервере вновь проверяются конфигурация и версия. ПолучитьРазделительПутиСервера строит собственный серверный путь; ПолучитьМаскуВсеФайлыСервера и текущая маска используются только на этой стороне.
Сервер создаёт свой server-source.txt из SERVER-85, выполняет два нерекурсивных поиска и сравнивает фактически прочитанные байты. Заранее заданных серверных путей нет.
Очистка сервера проверяет подтверждение создания, суффикс и точный свой файл. Удаление файла и проверка пустоты каталога выполняются независимо; обе ошибки сохраняются.
На клиент возвращается только структура строкового отчёта после успешной серверной очистки. Клиент независимо удаляет собственный опыт и сообщает успех только при отсутствии обеих ошибок.
Как проверить результат
Каждая из двух масок клиента находит ровно его source.txt; обе серверные маски — ровно server-source.txt в собственном серверном каталоге.
Клиентский файл подтверждён как ABC-85, серверный как SERVER-85. Совпадение имён или размеров не заменяет сравнение содержимого.
В клиентской части нет вызовов ПолучитьРазделительПутиСервера и ПолучитьМаскуВсеФайлыСервера. Они находятся только под НаСервереБезКонтекста.
На одинаковой ОС маски/разделители могут совпасть; на разных могут отличаться. Это не меняет проверку собственных файлов и не делает серверный путь доступным клиенту.
После штатного успеха оба опыта очищены. При ошибке результат не выдаётся за успех; неизвестные объекты и непустые каталоги остаются.
Ожидаемый результат
При собственном ручном успешном запуске правильные маски находят свой файл на каждой стороне, реальные байты совпадают, а оба собственных каталога удалены после проверки пустоты.
На что обратить внимание
ПолучитьРазделительПутиСервера и ПолучитьМаскуВсеФайлыСервера вызывают исключение на клиенте в клиент-серверном варианте. Доступность «толстый клиент» не отменяет это примечание; здесь оба вызова находятся на сервере.
ПолучитьМаскуВсеФайлы определяется текущей стороной исполнения. Одна и та же процедура формы не исполняется одновременно на обеих сторонах; директивы задают контекст.
В файловом варианте серверный контекст может исполняться локально. Это не повод переставлять серверные вызовы в клиентский обработчик: модуль сохраняет правильные директивы.
Серверный путь в отчёте предназначен для диагностики владельцем, не для НайтиФайлы на клиенте. Даже совпавшие строки путей на разных компьютерах относятся к разным файловым системам.
Маска «все файлы» не является рекурсивным обходом и не является гарантией обнаружения всех системных, скрытых или запрещённых по правам объектов. Урок проверяет только свой один обычный txt-файл.
Уникальное имя и Существует не являются атомарным резервированием. Учебные каталоги должны быть закрыты от сторонних писателей; это не production-защита от подмены и гонок.
УдалитьФайлы может рекурсивно удалить каталог. Здесь это допускается только для подтверждённого собственного пустого каталога; файл заранее проверяется на ЭтоКаталог=Ложь.
Очистка использует * для нерекурсивной проверки любых остатков, а не только *.txt. Неизвестные файлы и подкаталоги никогда не удаляются автоматически.
Если сервер аварийно завершился или файловые права не позволяют очистку, гарантии удаления нет. Администратор разбирает собственный путь; пользовательские каталоги не очищаются.
Нет сетевого диска, внешнего API, архива и резервного копирования данных. Все операции файлов в этом уроке — только будущий отдельный ручной учебный опыт.
Проверка согласия и имени пустой базы — ограничение учебного стенда, не система авторизации production-сервиса. Серверный метод не должен принимать произвольные пути от недоверенного клиента.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.