Часто разработчики и системные администраторы сталкиваются с плавающей проблемой, когда система внезапно прерывает работу с сообщением вида: "Ошибка при выполнении файловой операции 'C:\Users\USR1CV8\AppData\Local\Temp\v8_1BF4_352.mxl'". Особенно неприятно то, что ошибка возникает не всегда: один раз документ открывается штатно, а в другой момент времени — вываливается с предупреждением. Давайте подробно разберем причины такого поведения и рассмотрим различные пути решения проблемы.
Каталог Temp используется платформой 1С для хранения промежуточных данных, формирования отчетов, сохранения печатных форм (например, в PDF) перед их отправкой и множества других служебных операций. Если несколько процессов или сторонних программ пытаются получить доступ к одному и тому же файлу одновременно, возникает конфликт блокировок. Рассмотрим основные инфраструктурные факторы, из-за которых это происходит:
Записать(), происходит ошибка доступа.USR1CV8 есть явные права NTFS "Полный доступ" на весь каталог временных файлов.Очень часто причина кроется в самом прикладном коде конфигурации. Рассмотрим пример функции, которая конвертирует формат цвета через промежуточный MXL файл на диске:
Function cmGetAbsoluteColor(pColor) Export
If pColor.Type = ColorType.Absolute Then
Return pColor;
EndIf;
vSD = New SpreadsheetDocument;
vSD.Area("R1C1").BackColor = pColor;
vTF = GetTempFileName("mxl");
vSD.Write(vTF, SpreadsheetDocumentFileType.MXL7);
vSD.Read(vTF);
vColor = vSD.Area("R1C1").BackColor;
vSD = Undefined;
DeleteFiles(vTF);
Return vColor;
EndFunction
В этом коде разработчики создают объект ТабличныйДокумент, закрашивают ячейку, сохраняют документ на диск с помощью GetTempFileName, а затем снова читают файл с диска. Постоянное обращение к жесткому диску для такой простой операции создает колоссальную нагрузку на файловую систему сервера и провоцирует ошибки, если файл не успел освободиться или был заблокирован сторонней программой.
Давайте перепишем этот код, полностью исключив обращение к диску. Современные платформы 1С поддерживают работу с объектом ПотокВПамяти. Посмотрим, как это выглядит:
&НаСервере
Function cmGetAbsoluteColor(pColor) Export
If pColor.Вид = ВидЦвета.Абсолютный Then
Return pColor;
EndIf;
// Создаем виртуальный поток в оперативной памяти
Поток = Новый ПотокВПамяти();
vSD = Новый ТабличныйДокумент;
vSD.Область("R1C1").ЦветФона = pColor;
// Записываем документ прямо в оперативную память
vSD.Записать(Поток, ТипФайлаТабличногоДокумента.MXL7);
// Возвращаем курсор в начало потока для чтения
Поток.Перейти(0, ПозицияВПотоке.Начало);
vSD.Прочитать(Поток, СпособЧтенияЗначенийТабличногоДокумента.Значение);
vColor = vSD.Область("R1C1").BackColor;
// Очищаем память
Поток.Закрыть();
Поток = Неопределено;
vSD = Неопределено;
Return vColor;
EndFunction
Этот подход гарантированно решает проблему ошибок файловых операций, так как файл физически не создается в папке Temp, а все вычисления происходят молниеносно в оперативной памяти.
Если отказаться от сохранения на диск нельзя (например, мы генерируем PDF-файл бронирования для отправки по электронной почте), мы должны убедиться, что имена файлов абсолютно уникальны. Часто в коде используют простые конструкции, зависящие от номера документа, которые при одновременной печати двумя пользователями дадут сбой.
Рассмотрим безопасный метод генерации имени файла:
Функция УникальноеИмяВременногоФайла(Расширение)
Возврат КаталогВременныхФайлов() + Строка(Новый УникальныйИдентификатор) + "." + Расширение;
КонецФункции
При использовании объекта УникальныйИдентификатор риск совпадения имен файлов сводится к абсолютному нулю. Однако стоит учитывать, что метод ПолучитьИмяВременногоФайла может быть недоступен на веб-клиенте, поэтому генерация через каталог и GUID является предпочтительной.
Если код исправлен, а ошибки продолжают возникать, применим меры на уровне системного администрирования:
C:\Users\USR1CV8\AppData\Local\Temp\) в абсолютные исключения антивирусного сканера.USR1CV8 и полностью удалить все временные файлы, кэш метаданных и файлы блокировок snccntx. Только после этого запустим службу обратно. Стандартный перезапуск не всегда вычищает зависшие дескрипторы.Наконец, проанализируем прикладные настройки вашей конфигурации. В ряде случаев, постоянная запись данных на диск может быть вызвана активированными фоновыми рассылками или автоматическим формированием печатных форм. Иногда простейшим решением является отключение этой опции в параметрах программы (например, если отправка подтверждений бронирования в PDF временно не используется клиентами), что моментально устранит лишнюю нагрузку и избавит от ошибок файловых операций.