Копирование файлов

Little Friend 29 2 1

Копирование файлов из одного каталога в другой

Навеяно публикацией
Изначально не понравился метод определения типа файла - файл это или каталог. Автор считает, что если файл не имеет расширения, то это каталог, что в корне не правильно. В итоге привожу "правильную" реализацию. А точнее, три:

  1. синхронное копирование файлов;
  2. асинхронное копирование файлов с использованием методов последних версий платформы "Асинх";
  3. асинхронное копирование файлов с использованием оповещений.

Преимущество использования асинхронных методов на клиенте (через новые методы "...Асинх" или оповещений) очевидна - пользователь может продолжать работать с программой, пока выполняется копирование файлов.
Примечание. Для того, чтобы код был платформонезависим (работал и под Windows, и Linux) необходимо определить функцию разделителя каталогов ("/" или "\"). Но чтобы не усложнять код, здесь это не учитывается.

Синхронное копирование файлов.

Тут всё просто (используется рекурсия).

Процедура СкопироватьФайлы(Знач Источник, Знач Приемник)
	КаталогПриемник = Новый Файл(Приемник);
	Если Не КаталогПриемник.Существует() Тогда
		СоздатьКаталог(КаталогПриемник.ПолноеИмя);
	КонецЕсли;
	
	Файлы = НайтиФайлы(Источник, "*.*", Ложь);
	Для каждого Файл Из Файлы Цикл
		ПолноеИмяПриемника = КаталогПриемник.ПолноеИмя + "\" + Файл.Имя;
		Если Файл.ЭтоКаталог() Тогда
			СкопироватьФайлы(Файл.ПолноеИмя, ПолноеИмяПриемника);
		Иначе
			КопироватьФайл(Файл.ПолноеИмя, ПолноеИмяПриемника);
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры

Асинхронное копирование файлов с использованием методов последних версий платформы "Асинх".

Тут, практически, всё так же, только добавлены новые ключевые слова "Асинх" / "Ждать" и вызов аналогичных методов с добавлением "Асинх" на конце.

Асинх Процедура СкопироватьФайлыАсинх(Знач Источник, Знач Приемник)
	КаталогПриемник = Новый Файл(Приемник);
	Если Не Ждать КаталогПриемник.СуществуетАсинх() Тогда
		Ждать СоздатьКаталогАсинх(КаталогПриемник.ПолноеИмя);
	КонецЕсли;
	
	Файлы = Ждать НайтиФайлыАсинх(Источник, "*.*", Ложь);
	Для каждого Файл Из Файлы Цикл
		ПолноеИмяПриемника = КаталогПриемник.ПолноеИмя + "\" + Файл.Имя;
		Если Файл.ЭтоКаталог() Тогда
			СкопироватьФайлы(Файл.ПолноеИмя, ПолноеИмяПриемника);
		Иначе
			Ждать КопироватьФайлАсинх(Файл.ПолноеИмя, ПолноеИмяПриемника);
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры

Асинхронное копирование файлов с использованием оповещений.

А вот так приходилось "мучаться" до появления асинхронных методов, когда была доступна только обработка оповещений. Только сравните эту "портянку" кода и его читабельность (как говорится, без пол-литры не разберёшься) по сравнению с предыдущими.

&НаКлиенте
Процедура НачатьКопированиеФайлов(Знач Источник, Знач Приемник, ОповещениеОЗавершении = Неопределено)
	Контекст = Новый Структура;
	Контекст.Вставить("Источник", Источник);
	Контекст.Вставить("Приемник", Приемник);
	Контекст.Вставить("ОповещениеОЗавершении", ОповещениеОЗавершении);
	КаталогПриемник = Новый Файл(Приемник);
	Оповещение = Новый ОписаниеОповещения("ПроверкаСуществованияКаталогаЗавершение", ЭтотОбъект, Контекст);
	КаталогПриемник.НачатьПроверкуСуществования(Оповещение);
КонецПроцедуры

&НаКлиенте
Процедура ПроверкаСуществованияКаталогаЗавершение(Существует, Контекст) Экспорт
	Если Не Существует Тогда
		Оповещение = Новый ОписаниеОповещения("СозданиеКаталогаЗавершение", ЭтотОбъект, Контекст);
		НачатьСозданиеКаталога(Оповещение, Контекст.Приемник);
	Иначе
		НачатьПоискФайловВИсточнике(Контекст);
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура СозданиеКаталогаЗавершение(ИмяКаталога, Контекст) Экспорт
	НачатьПоискФайловВИсточнике(Контекст);
КонецПроцедуры

&НаКлиенте
Процедура НачатьПоискФайловВИсточнике(Контекст) Экспорт
	Оповещение = Новый ОписаниеОповещения("ПоискФайловЗавершение", ЭтотОбъект, Контекст);
	НачатьПоискФайлов(Оповещение, Контекст.Источник, "*.*", Ложь);
КонецПроцедуры

&НаКлиенте
Процедура ПоискФайловЗавершение(Файлы, Контекст) Экспорт
	Контекст.Вставить("Файлы", Файлы);
	НачатьКопированиеФайлаИзИсточника(Контекст);
КонецПроцедуры

&НаКлиенте
Процедура НачатьКопированиеФайлаИзИсточника(Контекст) Экспорт
	Если Контекст.Файлы.Количество() = 0 Тогда
		Если Контекст.ОповещениеОЗавершении <> Неопределено Тогда
			ВыполнитьОбработкуОповещения(Контекст.ОповещениеОЗавершении, Истина);
		КонецЕсли;
		Возврат;
	КонецЕсли;
	
	Файл = Контекст.Файлы[0];
	Оповещение = Новый ОписаниеОповещения("ПроверкаЭтоКаталогЗавершение", ЭтотОбъект, Контекст);
	Файл.НачатьПроверкуЭтоКаталог(Оповещение);
КонецПроцедуры

&НаКлиенте
Процедура ПроверкаЭтоКаталогЗавершение(ЭтоКаталог, Контекст) Экспорт
	ПолноеИмяПриемника = Контекст.Приемник + "\" + Контекст.Файлы[0].Имя;
	Оповещение = Новый ОписаниеОповещения("КопированиеФайлаЗавершение", ЭтотОбъект, Контекст);
	
	Если ЭтоКаталог Тогда
		НачатьКопированиеФайлов(Контекст.Файлы[0].ПолноеИмя, ПолноеИмяПриемника, Оповещение);
	Иначе
		НачатьКопированиеФайла(Оповещение, Контекст.Файлы[0].ПолноеИмя, ПолноеИмяПриемника);
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура КопированиеФайлаЗавершение(Файл, Контекст) Экспорт
	Контекст.Файлы.Удалить(0);
	НачатьКопированиеФайлаИзИсточника(Контекст);
КонецПроцедуры
0

См. также

Копирование файлов

КодировкаФайловПрограммыРезервногоКопированияИБ (БСП)

ОбработатьФайлПослеКопированияФайла (БСП)

ЗаполнитьРеквизитыФайлаИзИсходногоФайла (БСП)

НаименованиеФоновогоРезервногоКопирования (БСП)

ИмяМетодаФоновогоРезервногоКопирования (БСП)

СкопироватьДокумент, Копирование документа

УстановитьНастройкиРезервногоКопирования (БСП)

ПараметрыРезервногоКопирования (БСП)

Модератору