Удаление файлов из 1С: диск, сервер, временное хранилище и тома
Содержание
Чтобы в 1С удалить файл с диска, вызовите метод встроенного языка УдалитьФайлы(Путь): он стирает один файл, а если передать каталог — каталог целиком со всем содержимым. Вторым параметром можно задать маску, например "*.tmp", и удалить только подходящие файлы.
Сложности начинаются дальше. Код работает на клиенте, а файл лежит на сервере. Файл занят, и 1С падает с Ошибка при вызове метода контекста (УдалитьФайлы). Временные файлы копятся гигабайтами, а база не худеет после удаления вложений. Для каждого случая есть свой приём, и все они укладываются в несколько строк кода на платформе 8.3.
Методы встроенного языка для удаления файлов
В платформе 8.3 для удаления есть три инструмента. Выбор зависит от того, где выполняется код и нужен ли асинхронный вызов.
| Метод | Где работает | Когда брать |
|---|---|---|
УдалитьФайлы(Путь, Маска) | сервер, толстый и тонкий клиент | обычный синхронный вызов |
УдалитьФайлыАсинх(Путь, Маска) | клиент, платформа 8.3.18 и выше | клиентский код с Асинх/Ждать |
НачатьУдалениеФайлов(Оповещение, Путь, Маска) | клиент, в том числе веб-клиент | старые релизы платформы, совместимость |
Удалить один файл
Перед удалением полезно проверить, есть ли файл. УдалитьФайлы по несуществующему пути обычно не ругается, но явная проверка делает код понятнее и позволяет записать в журнал, что удалять было нечего.
ПутьКФайлу = "D:\Обмен\выгрузка.xml";
Файл = Новый Файл(ПутьКФайлу);
Если Файл.Существует() И Файл.ЭтоФайл() Тогда
УдалитьФайлы(ПутьКФайлу);
КонецЕсли;
Удалить файлы по маске
// Все файлы с расширением tmp в каталоге обмена
УдалитьФайлы("D:\Обмен", "*.tmp");
Вызов УдалитьФайлы("D:\Обмен") без маски удалит сам каталог вместе со всем, что в нём лежит. Проверяйте путь перед вызовом: пустая строка или опечатка в переменной может указать совсем не на ту папку.
Асинхронный вариант на клиенте
В клиентском коде современных конфигураций синхронные вызовы работы с файлами часто запрещены режимом совместимости. Тогда используйте асинхронный метод:
&НаКлиенте
Асинх Процедура УдалитьВыгрузку(Команда)
Ждать УдалитьФайлыАсинх("D:\Обмен\выгрузка.xml");
ПоказатьОповещениеПользователя("Файл удалён");
КонецПроцедуры
В веб-клиенте доступ к локальному диску появляется только после установки расширения работы с файлами. Без него браузер не даст 1С удалить файл пользователя.
Временные файлы и каталоги: создать и не забыть убрать
Платформа не чистит за разработчиком. Имя от ПолучитьИмяВременногоФайла("xlsx") указывает в каталог временных файлов, но сам файл после записи живёт там, пока его не удалят. На сервере такие хвосты от выгрузок и печати за полгода легко набирают десятки гигабайт.
Надёжная схема — удалять в обеих ветках, и при успехе, и при ошибке:
ИмяВременного = ПолучитьИмяВременногоФайла("xlsx");
Попытка
ТабДок.Записать(ИмяВременного, ТипФайлаТабличногоДокумента.XLSX);
ДвоичныеДанные = Новый ДвоичныеДанные(ИмяВременного);
Исключение
УдалитьФайлы(ИмяВременного);
ВызватьИсключение;
КонецПопытки;
УдалитьФайлы(ИмяВременного);
Если промежуточных файлов несколько, удобнее завести отдельный подкаталог и в конце удалить его одной строкой:
Каталог = КаталогВременныхФайлов() + Строка(Новый УникальныйИдентификатор);
СоздатьКаталог(Каталог);
// ... пишем в Каталог любое число файлов ...
УдалитьФайлы(Каталог);
💡 В конфигурациях на БСП 3.x для этого есть общий модуль ФайловаяСистема с процедурами создания и удаления временного каталога и временного файла. Они учитывают особенности клиента и сервера, поэтому в типовых доработках лучше пользоваться ими.
Что делать с уже накопленным мусором
Временные файлы платформы называются по шаблону вида v8_XXXX_N.tmp и лежат в каталоге %TEMP% того пользователя Windows, под которым работает клиент или сервер. На рабочем месте их можно удалить вручную, предварительно закрыв все окна 1С.
На сервере каталог %TEMP% принадлежит учётной записи службы сервера 1С. Чистите его в нерабочее время: файл, который сейчас нужен рабочему процессу, не удалится или, что хуже, пропадёт посреди формирования отчёта у пользователя.
Удаление файлов на сервере 1С: чей это диск
Самая частая путаница: код в серверной процедуре видит не диск пользователя, а диск сервера. УдалитьФайлы("C:\Выгрузка\отчёт.xml") в процедуре с директивой &НаСервере удалит файл на компьютере, где работает рабочий процесс rphost, а не на компьютере бухгалтера.
На что смотреть при удалении файлов на сервере:
- 🖥️ Права. Процесс работает от учётной записи службы. При стандартной установке на Windows это
USR1CV8, на Linux —usr1cv8. У неё должно быть право на изменение каталога. - 🌐 Сетевые диски. Буквы подключённых дисков вроде
Z:служба не видит. Пишите путь в формате UNC:\\fileserver\obmen\выгрузка.xml, а права на общую папку выдавайте учётной записи службы. - 🧩 Несколько рабочих серверов в кластере. Вызов может выполниться на любом из них. Локальный путь
D:\Обменна одном сервере на другом не существует. Для обмена используйте общий сетевой каталог. - 🔒 Безопасный режим. Внешние обработки и расширения в безопасном режиме к файловой системе не обращаются. Доступ к нужному каталогу открывают через профиль безопасности в кластере серверов.
Сервер на Linux: пути и регистр
На сервере под Linux путь вида D:\Обмен не существует вовсе. Каталоги там начинаются с /, например /var/1c/obmen, а имена файлов чувствительны к регистру: Выгрузка.xml и выгрузка.xml — два разных файла.
Не склеивайте путь с обратной косой чертой вручную. Разделитель для текущей системы возвращает функция ПолучитьРазделительПути():
Путь = КаталогОбмена + ПолучитьРазделительПути() + ИмяФайла;
После удаления проверьте результат: Новый Файл(Путь).Существует() должен вернуть Ложь. Если вернул Истина без ошибки, удаление не сработало: проверьте, как собран путь и на какой машине выполняется код.
Если файл нужно удалить у пользователя, а решение принимается на сервере, верните с сервера путь или признак и удаляйте в клиентской процедуре.
Плановая очистка каталога обмена
Для папок обмена удобно повесить на регламентное задание удаление файлов старше нескольких дней:
Граница = ТекущаяДатаСеанса() - 7 * 86400; // 7 дней в секундах
Найденные = НайтиФайлы("\\fileserver\obmen", "*.xml", Ложь);
Для Каждого Файл Из Найденные Цикл
Если Файл.ЭтоФайл() И Файл.ПолучитьВремяИзменения() < Граница Тогда
Попытка
УдалитьФайлы(Файл.ПолноеИмя);
Исключение
ЗаписьЖурналаРегистрации("Очистка каталога обмена",
УровеньЖурналаРегистрации.Предупреждение, , Файл.ПолноеИмя,
ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
Третий параметр НайтиФайлы — поиск в подкаталогах. Здесь он Ложь, чтобы не задеть вложенные папки. Ошибка по одному файлу не останавливает обработку остальных, а попадает в журнал регистрации.
Как удалить присоединённые файлы и очистить хранилище
В типовых конфигурациях вложения к документам и справочникам — это не файлы на диске, а элементы справочников присоединённых файлов. Удалять их через проводник нельзя.
Удаление вложения в программе
- Откройте документ или элемент справочника и перейдите к присоединённым файлам (значок скрепки или команда в командной панели формы).
- Выделите файл и пометьте его на удаление.
- Физически объект удаляется обработкой удаления помеченных объектов. В 1С:Бухгалтерии 3.0 она находится в
Администрирование → Обслуживание → Корректировка данных → Удаление помеченных объектов.
Перед запуском обработки сделайте резервную копию: она удаляет все помеченные объекты базы, не только файлы.
Где на самом деле лежит содержимое
Содержимое присоединённого файла хранится одним из двух способов. Это задаётся в настройках работы с файлами в разделе Администрирование.
| Способ хранения | Где данные | Что важно при удалении |
|---|---|---|
| В информационной базе | внутри таблиц базы | место освобождается внутри базы, размер файла базы сам не уменьшается |
| В томах на диске | в каталогах томов хранения файлов | удаляйте только через программу, не из папки тома |
Если стереть файл прямо из каталога тома, карточка в 1С останется, а при открытии вложения пользователь получит ошибку. Удалять вложения нужно только через карточку и удаление помеченных.
После удаления крупных вложений файловая база 1Cv8.1CD сама не сжимается. Освободить место на диске помогает Конфигуратор → Администрирование → Тестирование и исправление с флажком сжатия таблиц. Для этой операции нужен монопольный доступ, поэтому все пользователи должны выйти из базы. В клиент-серверном варианте место освобождают средствами СУБД.
Временное хранилище — это тоже «удаление файла»
Если файл передавался между клиентом и сервером через ПоместитьВоВременноеХранилище, он висит в памяти сеанса. Освобождайте его явно, когда данные больше не нужны:
УдалитьИзВременногоХранилища(АдресФайла);
Если при помещении указан уникальный идентификатор формы, данные удалятся при её закрытии. Без идентификатора они живут до конца сеанса. При загрузке десятков больших файлов подряд это заметно по памяти рабочего процесса.
Массовое удаление через COM и командную строку
Встроенного метода хватает для большинства задач. Внешние средства нужны, когда файлов десятки тысяч, когда мешает атрибут «только чтение» или когда надо удалить файлы по сложному правилу.
Scripting.FileSystemObject (только Windows)
FSO = Новый COMОбъект("Scripting.FileSystemObject");
Попытка
FSO.DeleteFile("D:\Обмен\*.tmp", Истина);
Исключение
// DeleteFile выдаёт ошибку, если по маске не нашлось ни одного файла
КонецПопытки;
Второй параметр Истина удаляет и файлы с атрибутом «только чтение». Для каталогов есть аналогичный метод DeleteFolder.
Командная строка
ЗапуститьПриложение("cmd /c del /q ""D:\Обмен\*.tmp""", , Ложь);
Последний параметр Ложь означает, что 1С не ждёт завершения команды. Результат удаления при этом не виден, ошибки молча теряются.
| Способ | Плюсы | Риски |
|---|---|---|
УдалитьФайлы | работает везде, ошибки ловятся Попытка | медленнее на огромных объёмах |
COM FileSystemObject | маски, «только чтение» | только Windows, нужен COM на сервере |
cmd /c del, rm | быстро | нет контроля ошибок, опасен при неверном пути |
| Внешняя компонента | любая логика | нужно устанавливать и сопровождать |
Команды del /s, rd /s и rm -rf с путём из переменной — самый короткий путь к потере данных. Если переменная окажется пустой, команда отработает по текущему каталогу. Проверяйте путь в коде до запуска.
В клиент-серверном варианте на Linux COM недоступен. Там используйте УдалитьФайлы или нативную внешнюю компоненту.
Файл занят или не удаляется: причины и решения
Типичный текст: Ошибка при вызове метода контекста (УдалитьФайлы) и следом описание от операционной системы — нет доступа или файл используется другим процессом.
Основные причины:
- 📂 Файл не закрыт самой 1С. Объекты
ЧтениеТекста,ЗаписьТекста,ЧтениеXML,ЗаписьXML,ЧтениеZipФайладержат файл до вызоваЗакрыть(). Удаление сразу после чтения без закрытия падает. - 📊 Открыт в Excel или Word через COM. Пока вы не вызвали
Quit()у приложения и не очистили переменную, процесс Excel держит книгу. - 🔐 Атрибут «только чтение». Снимите его перед удалением:
Новый Файл(Путь).УстановитьТолькоЧтение(Ложь). - 👤 Нет прав у учётной записи. На сервере это учётная запись службы, а не пользователь 1С.
- 🛡️ Антивирус проверяет файл. Обычно это секунды. Повторная попытка чуть позже помогает.
Отложенное удаление
Пауза в серверном коде — плохая идея: она держит рабочий процесс. На клиенте повторите попытку через ПодключитьОбработчикОжидания("ПовторитьУдаление", 5, Истина). На сервере сохраните путь неудавшегося файла и удалите его следующим запуском регламентного задания. Так пользователь не ждёт, а мусор всё равно уходит.
Полный текст ошибки для журнала даёт ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()). По нему видно, на каком файле и в какой строке модуля всё остановилось.