Добавить файл том. Добавляет файл в один из томов (где есть свободное место).
// Добавляет файл в один из томов (где есть свободное место).
//
// Параметры:
// ДвоичныеДанныеИлиПуть - ДвоичныеДанные, Строка - двоичные данные файла или полный путь к файлу на диске.
// ВремяИзмененияУниверсальное - Дата - универсальное время, которое будет установлено файлу как время последнего
// изменения.
// ИмяБезРасширения - Строка - имя файла без расширения.
// Расширение - Строка - расширение файла без точки.
// НомерВерсии - Строка - номер версии файла. Если указан, то имя файла для хранения на диске формируется
// как:
// ИмяБезРасширения + "." + НомерВерсии + "." + Расширение
// в противном случае, ИмяБезРасширения + "." + Расширение.
// Зашифрован - Булево - если Истина, то к полному имени файла будет добавлено расширение ".p7m".
// ДатаДляРазмещенияВТоме - Дата - если не указано, то используется текущее время сеанса.
//
// Возвращаемое значение:
// Структура - со свойствами:
// * Том - СправочникСсылка.ТомаХраненияФайлов - том, в котором был размещен файл.
// * ПутьКФайлу - Строка - путь, по которому был размещен файл в томе.
//
Функция ДобавитьФайлВТом(ДвоичныеДанныеИлиПуть, ВремяИзмененияУниверсальное, ИмяБезРасширения, Расширение,
НомерВерсии = "", Зашифрован = Ложь, ДатаДляРазмещенияВТоме = Неопределено) Экспорт
ОжидаемыеТипы = Новый Массив;
ОжидаемыеТипы.Добавить(Тип("ДвоичныеДанные"));
ОжидаемыеТипы.Добавить(Тип("Строка"));
ОбщегоНазначенияКлиентСервер.ПроверитьПараметр("РаботаСФайламиСлужебный.ДобавитьФайлВТом", "ДвоичныеДанныеИлиПуть", ДвоичныеДанныеИлиПуть,
Новый ОписаниеТипов(ОжидаемыеТипы));
УстановитьПривилегированныйРежим(Истина);
СсылкаНаТом = Справочники.ТомаХраненияФайлов.ПустаяСсылка();
КраткоеОписаниеВсехОшибок = ""; // Ошибки со всех томов.
ПодробноеОписаниеВсехОшибок = ""; // Для журнала регистрации.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТомаХраненияФайлов.Ссылка
|ИЗ
| Справочник.ТомаХраненияФайлов КАК ТомаХраненияФайлов
|ГДЕ
| ТомаХраненияФайлов.ПометкаУдаления = ЛОЖЬ
|
|УПОРЯДОЧИТЬ ПО
| ТомаХраненияФайлов.ПорядокЗаполнения";
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Количество() = 0 Тогда
ВызватьИсключение НСтр("ru = 'Нет ни одного тома для размещения файла.'");
КонецЕсли;
Пока Выборка.Следующий() Цикл
СсылкаНаТом = Выборка.Ссылка;
ПутьКТому = ПолныйПутьТома(СсылкаНаТом);
// Добавляем слэш в конце, если его нет.
ПутьКТому = ОбщегоНазначенияКлиентСервер.ДобавитьКонечныйРазделительПути(ПутьКТому);
// Имя файла для хранения на диске формировать следующим образом
// - имя файла.номер версии.расширение файла.
Если ПустаяСтрока(НомерВерсии) Тогда
ИмяФайла = ИмяБезРасширения + "." + Расширение;
Иначе
ИмяФайла = ИмяБезРасширения + "." + НомерВерсии + "." + Расширение;
КонецЕсли;
Если Зашифрован Тогда
ИмяФайла = ИмяФайла + "." + "p7m";
КонецЕсли;
Попытка
Если ТипЗнч(ДвоичныеДанныеИлиПуть) = Тип("ДвоичныеДанные") Тогда
РазмерФайла = ДвоичныеДанныеИлиПуть.Размер();
Иначе // Считаем, что иначе это путь к файлу на диске.
ФайлИсточник = Новый Файл(ДвоичныеДанныеИлиПуть);
Если ФайлИсточник.Существует() Тогда
РазмерФайла = ФайлИсточник.Размер();
Иначе
ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Не удалось добавить файл ""%1"" ни в один из томов, т.к. он отсутствует.
|Возможно, файл удален антивирусной программой.
|Обратитесь к администратору.'"),
ИмяФайла);
ВызватьИсключение ТекстОшибки;
КонецЕсли;
КонецЕсли;
// Если МаксимальныйРазмер = 0 - нет ограничения на размер файлов на томе.
Если СсылкаНаТом.МаксимальныйРазмер <> 0 Тогда
ТекущийРазмерВБайтах = ПодсчитатьРазмерФайловНаТоме(СсылкаНаТом.Ссылка);
НовыйРазмерВБайтах = ТекущийРазмерВБайтах + РазмерФайла;
НовыйРазмер = НовыйРазмерВБайтах / (1024 * 1024);
Если НовыйРазмер > СсылкаНаТом.МаксимальныйРазмер Тогда
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Превышен максимальный размер тома (%1 Мб).'"),
СсылкаНаТом.МаксимальныйРазмер);
КонецЕсли;
КонецЕсли;
Дата = ТекущаяДатаСеанса();
Если ДатаДляРазмещенияВТоме <> Неопределено Тогда
Дата = ДатаДляРазмещенияВТоме;
КонецЕсли;
// Использование абсолютного формата даты "ДФ" в следующей строке
// является правильным, так как дата используется не для просмотра пользователем.
ПутьДня = Формат(Дата, "ДФ=ггггММдд") + ПолучитьРазделительПути();
ПутьКТому = ПутьКТому + ПутьДня;
ИмяФайлаСПутем = РаботаСФайламиСлужебныйКлиентСервер.ПолучитьУникальноеИмяСПутем(ПутьКТому, ИмяФайла);
ПолноеИмяФайлаСПутем = ПутьКТому + ИмяФайлаСПутем;
Если ТипЗнч(ДвоичныеДанныеИлиПуть) = Тип("ДвоичныеДанные") Тогда
ДвоичныеДанныеИлиПуть.Записать(ПолноеИмяФайлаСПутем);
Иначе // Считаем, что иначе это путь к файлу на диске.
КопироватьФайл(ДвоичныеДанныеИлиПуть, ПолноеИмяФайлаСПутем);
КонецЕсли;
// Установка времени изменения файла таким, как оно стоит в текущей версии.
ФайлНаДиске = Новый Файл(ПолноеИмяФайлаСПутем);
ФайлНаДиске.УстановитьУниверсальноеВремяИзменения(ВремяИзмененияУниверсальное);
ФайлНаДиске.УстановитьТолькоЧтение(Истина);
Возврат Новый Структура("Том,ПутьКФайлу", СсылкаНаТом, ПутьДня + ИмяФайлаСПутем);
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
Если ПодробноеОписаниеВсехОшибок <> "" Тогда
ПодробноеОписаниеВсехОшибок = ПодробноеОписаниеВсехОшибок + Символы.ПС + Символы.ПС;
КраткоеОписаниеВсехОшибок = КраткоеОписаниеВсехОшибок + Символы.ПС + Символы.ПС;
КонецЕсли;
ШаблонОписанияОшибки =
НСтр("ru = 'Ошибка при добавлении файла ""%1""
|в том ""%2"" (%3):
|""%4"".'");
ПодробноеОписаниеВсехОшибок = ПодробноеОписаниеВсехОшибок
+ СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
ШаблонОписанияОшибки,
ИмяФайла,
Строка(СсылкаНаТом),
ПутьКТому,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке));
КраткоеОписаниеВсехОшибок = КраткоеОписаниеВсехОшибок
+ СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
ШаблонОписанияОшибки,
ИмяФайла,
Строка(СсылкаНаТом),
ПутьКТому,
КраткоеПредставлениеОшибки(ИнформацияОбОшибке));
// Надо переходить к следующему тому.
Продолжить;
КонецПопытки;
КонецЦикла;
УстановитьПривилегированныйРежим(Ложь);
// Запись в журнал регистрации для администратора
// здесь выдадим ошибки со всех томов.
ШаблонСообщенияОбОшибке = НСтр("ru = 'Не удалось добавить файл ни в один из томов.
|Список ошибок:
|
|%1'");
ЗаписьЖурналаРегистрации(
НСтр("ru = 'Файлы.Добавление файла'", ОбщегоНазначения.КодОсновногоЯзыка()),
УровеньЖурналаРегистрации.Ошибка,,,
СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонСообщенияОбОшибке, ПодробноеОписаниеВсехОшибок));
Если Пользователи.ЭтоПолноправныйПользователь() Тогда
СтрокаИсключения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонСообщенияОбОшибке, КраткоеОписаниеВсехОшибок);
Иначе
// Сообщение обычному пользователю.
СтрокаИсключения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Не удалось добавить файл:
|""%1.%2"".
|
|Обратитесь к администратору.'"),
ИмяБезРасширения, Расширение);
КонецЕсли;
ВызватьИсключение СтрокаИсключения;
КонецФункции
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2019, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////
Канал FastCode 1C в Телеграм! Шаблоны кода, статьи, полезные советы, курсы по 1С (8К участников)