При разработке интеграций и обработке файловых хранилищ в 1С часто возникает задача: понять, расположен ли указанный файл на локальном компьютере или находится на сетевом ресурсе. Необходимость такой проверки обусловлена разницей в скорости чтения и записи, надежностью сетевого соединения, а также особенностями прав доступа служб сервера 1С.
Проанализируем доступные подходы, разберем возможные подводные камни и рассмотрим рабочие программные решения.
Самое очевидное решение, которое приходит в голову разработчику, — проверить начало строки полного пути файла на наличие двойного слэша:
Если Лев(ПолноеИмяФайла, 2) = "\\" Тогда
// Файл находится в сети (UNC-путь)
КонецЕсли;
Однако такой подход решает задачу лишь частично. Рассмотрим сценарии, в которых строковая проверка дает сбой:
Z:\). В этом случае полный путь будет выглядеть как Z:\documents\file.txt, и проверка на двойной слэш вернет Ложь, хотя файл фактически лежит на удаленном сервере.C:\ может являться символической ссылкой (symlink) или точкой соединения (junction), ведущей на удаленный сетевой ресурс. Внешне путь остается полностью локальным.Для того чтобы корректно распознать смонтированные сетевые диски под операционной системой Windows, обратимся к средствам WMI (Windows Management Instrumentation). Через WMI можно получить список всех логических дисков в системе и их свойства.
Рассмотрим пример кода на платформе 1С, который опрашивает класс Win32_LogicalDisk:
objLocator = Новый COMОбъект("WbemScripting.SWbemLocator");
objWMIService = objLocator.ConnectServer(".", "root\cimv2");
colDisks = objWMIService.ExecQuery("Select * from Win32_LogicalDisk");
Для Каждого objDisk Из colDisks Цикл
Если objDisk.DriveType = 1 Тогда
Сообщить("Диск: " + objDisk.DeviceID + " - Тип не определен (No root directory)");
ИначеЕсли objDisk.DriveType = 2 Тогда
Сообщить("Диск: " + objDisk.DeviceID + " - Съемный диск (Removable drive)");
ИначеЕсли objDisk.DriveType = 3 Тогда
Сообщить("Диск: " + objDisk.DeviceID + " - Локальный жесткий диск (Local hard disk)");
ИначеЕсли objDisk.DriveType = 4 Тогда
Сообщить("Диск: " + objDisk.DeviceID + " - Сетевой диск (Network disk)");
ИначеЕсли objDisk.DriveType = 5 Тогда
Сообщить("Диск: " + objDisk.DeviceID + " - Оптический привод (Compact disk)");
ИначеЕсли objDisk.DriveType = 6 Тогда
Сообщить("Диск: " + objDisk.DeviceID + " - RAM-диск (RAM disk)");
Иначе
Сообщить("Диск: " + objDisk.DeviceID + " - Неизвестный тип диска");
КонецЕсли;
КонецЦикла;
Значение свойства DriveType = 4 однозначно свидетельствует о том, что буква диска сопоставлена с удаленным сетевым ресурсом.
Обращение к WMI может занимать заметное время при инициализации COM-объекта. Если требуется быстрая проверка конкретного пути на стороне клиента Windows, более легковесным решением будет использование объекта Scripting.FileSystemObject.
Разберем по шагам реализацию универсальной функции:
Функция ЭтоУдаленныйФайл(Знач ПолныйПуть) Экспорт
// 1. Проверяем классический UNC-путь
Если Лев(ПолныйПуть, 2) = "\\" Тогда
Возврат Истина;
КонецЕсли;
// 2. Проверяем букву диска через FileSystemObject
Попытка
ФСО = Новый COMОбъект("Scripting.FileSystemObject");
ИмяДиска = ФСО.GetDriveName(ПолныйПуть);
Если ЗначениеЗаполнено(ИмяДиска) Тогда
Диск = ФСО.GetDrive(ИмяДиска);
// DriveType = 3 соответствует сетевому диску (Remote)
Если Диск.DriveType = 3 Тогда
Возврат Истина;
КонецЕсли;
КонецЕсли;
Исключение
// Ошибка обращения к COM-объекту или отсутствие доступа к диску
Возврат Ложь;
КонецПопытки;
Возврат Ложь;
КонецФункции
Обратите внимание: штатный объект 1С Файл предоставляет только базовые атрибуты (размер, дату модификации, признак существования) и не умеет возвращать информацию о типе накопителя.
При разработке решений, работающих на Linux-серверах или кроссплатформенных клиентах, вызовы COM-объектов (WScript, WMI, Scripting.FileSystemObject) работать не будут. В среде Linux сетевые папки (SMB, NFS) монтируются непосредственно в файловую иерархию (например, в /mnt/share). В таких случаях для надежного определения сетевого расположения анализируют файл точек монтирования /proc/mounts либо используют внешние компоненты Native API.