Копирование файлов из одного каталога в другой
Навеяно публикацией
Изначально не понравился метод определения типа файла - файл это или каталог. Автор считает, что если файл не имеет расширения, то это каталог, что в корне не правильно. В итоге привожу "правильную" реализацию. А точнее, три:
Преимущество использования асинхронных методов на клиенте (через новые методы "...Асинх" или оповещений) очевидна - пользователь может продолжать работать с программой, пока выполняется копирование файлов.
Примечание. Для того, чтобы код был платформонезависим (работал и под Windows, и Linux) необходимо определить функцию разделителя каталогов ("/" или "\"). Но чтобы не усложнять код, здесь это не учитывается.
Тут всё просто (используется рекурсия).
Процедура СкопироватьФайлы(Знач Источник, Знач Приемник)
КаталогПриемник = Новый Файл(Приемник);
Если Не КаталогПриемник.Существует() Тогда
СоздатьКаталог(КаталогПриемник.ПолноеИмя);
КонецЕсли;
Файлы = НайтиФайлы(Источник, "*.*", Ложь);
Для каждого Файл Из Файлы Цикл
ПолноеИмяПриемника = КаталогПриемник.ПолноеИмя + "\" + Файл.Имя;
Если Файл.ЭтоКаталог() Тогда
СкопироватьФайлы(Файл.ПолноеИмя, ПолноеИмяПриемника);
Иначе
КопироватьФайл(Файл.ПолноеИмя, ПолноеИмяПриемника);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Тут, практически, всё так же, только добавлены новые ключевые слова "Асинх" / "Ждать" и вызов аналогичных методов с добавлением "Асинх" на конце.
Асинх Процедура СкопироватьФайлыАсинх(Знач Источник, Знач Приемник)
КаталогПриемник = Новый Файл(Приемник);
Если Не Ждать КаталогПриемник.СуществуетАсинх() Тогда
Ждать СоздатьКаталогАсинх(КаталогПриемник.ПолноеИмя);
КонецЕсли;
Файлы = Ждать НайтиФайлыАсинх(Источник, "*.*", Ложь);
Для каждого Файл Из Файлы Цикл
ПолноеИмяПриемника = КаталогПриемник.ПолноеИмя + "\" + Файл.Имя;
Если Файл.ЭтоКаталог() Тогда
СкопироватьФайлы(Файл.ПолноеИмя, ПолноеИмяПриемника);
Иначе
Ждать КопироватьФайлАсинх(Файл.ПолноеИмя, ПолноеИмяПриемника);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
А вот так приходилось "мучаться" до появления асинхронных методов, когда была доступна только обработка оповещений. Только сравните эту "портянку" кода и его читабельность (как говорится, без пол-литры не разберёшься) по сравнению с предыдущими.
&НаКлиенте
Процедура НачатьКопированиеФайлов(Знач Источник, Знач Приемник, ОповещениеОЗавершении = Неопределено)
Контекст = Новый Структура;
Контекст.Вставить("Источник", Источник);
Контекст.Вставить("Приемник", Приемник);
Контекст.Вставить("ОповещениеОЗавершении", ОповещениеОЗавершении);
КаталогПриемник = Новый Файл(Приемник);
Оповещение = Новый ОписаниеОповещения("ПроверкаСуществованияКаталогаЗавершение", ЭтотОбъект, Контекст);
КаталогПриемник.НачатьПроверкуСуществования(Оповещение);
КонецПроцедуры
&НаКлиенте
Процедура ПроверкаСуществованияКаталогаЗавершение(Существует, Контекст) Экспорт
Если Не Существует Тогда
Оповещение = Новый ОписаниеОповещения("СозданиеКаталогаЗавершение", ЭтотОбъект, Контекст);
НачатьСозданиеКаталога(Оповещение, Контекст.Приемник);
Иначе
НачатьПоискФайловВИсточнике(Контекст);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура СозданиеКаталогаЗавершение(ИмяКаталога, Контекст) Экспорт
НачатьПоискФайловВИсточнике(Контекст);
КонецПроцедуры
&НаКлиенте
Процедура НачатьПоискФайловВИсточнике(Контекст) Экспорт
Оповещение = Новый ОписаниеОповещения("ПоискФайловЗавершение", ЭтотОбъект, Контекст);
НачатьПоискФайлов(Оповещение, Контекст.Источник, "*.*", Ложь);
КонецПроцедуры
&НаКлиенте
Процедура ПоискФайловЗавершение(Файлы, Контекст) Экспорт
Контекст.Вставить("Файлы", Файлы);
НачатьКопированиеФайлаИзИсточника(Контекст);
КонецПроцедуры
&НаКлиенте
Процедура НачатьКопированиеФайлаИзИсточника(Контекст) Экспорт
Если Контекст.Файлы.Количество() = 0 Тогда
Если Контекст.ОповещениеОЗавершении <> Неопределено Тогда
ВыполнитьОбработкуОповещения(Контекст.ОповещениеОЗавершении, Истина);
КонецЕсли;
Возврат;
КонецЕсли;
Файл = Контекст.Файлы[0];
Оповещение = Новый ОписаниеОповещения("ПроверкаЭтоКаталогЗавершение", ЭтотОбъект, Контекст);
Файл.НачатьПроверкуЭтоКаталог(Оповещение);
КонецПроцедуры
&НаКлиенте
Процедура ПроверкаЭтоКаталогЗавершение(ЭтоКаталог, Контекст) Экспорт
ПолноеИмяПриемника = Контекст.Приемник + "\" + Контекст.Файлы[0].Имя;
Оповещение = Новый ОписаниеОповещения("КопированиеФайлаЗавершение", ЭтотОбъект, Контекст);
Если ЭтоКаталог Тогда
НачатьКопированиеФайлов(Контекст.Файлы[0].ПолноеИмя, ПолноеИмяПриемника, Оповещение);
Иначе
НачатьКопированиеФайла(Оповещение, Контекст.Файлы[0].ПолноеИмя, ПолноеИмяПриемника);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура КопированиеФайлаЗавершение(Файл, Контекст) Экспорт
Контекст.Файлы.Удалить(0);
НачатьКопированиеФайлаИзИсточника(Контекст);
КонецПроцедуры
КодировкаФайловПрограммыРезервногоКопированияИБ (БСП)
ОбработатьФайлПослеКопированияФайла (БСП)
ЗаполнитьРеквизитыФайлаИзИсходногоФайла (БСП)
НаименованиеФоновогоРезервногоКопирования (БСП)
ИмяМетодаФоновогоРезервногоКопирования (БСП)
СкопироватьДокумент, Копирование документа