Разработка и Конфигурация · 12 мин
Как узнать размер файла в 1С
Как узнать размер файла в 1С: объект Файл, метод Размер(), НайтиФайлы, работа на клиенте и сервере, проверка перед загрузкой. Примеры кода и типичные ошибки.
Во встроенном языке 1С размер файла чаще всего получают через объект Файл и его метод Размер(). Это стандартный способ, который работает и на толстом, и на тонком клиенте, и на сервере, однако у него есть важные особенности: файл должен физически существовать по указанному пути, а контекст выполнения (клиент или сервер) определяет, чья файловая система будет опрошена.
Задача определения размера возникает в типовых сценариях: проверка файла перед загрузкой в базу или отправкой по почте, контроль квот хранилища присоединенных файлов, валидация выгрузок перед обменом, мониторинг разрастания каталогов с архивами и логами. Во всех этих случаях алгоритм один и тот же: получить объект файла, вызвать метод, обработать возможные ошибки.
Ниже разобраны основные способы получения размера файла, различия между клиентским и серверным выполнением, работа с несколькими файлами и типичные ошибки, из-за которых код возвращает ноль или падает с исключением.
Базовый способ: объект Файл и метод Размер()
Основная конструкция выглядит так: создаётся объект Файл с полным путём, проверяется существование, затем вызывается Размер(). Метод возвращает число — количество байт. Если файла нет, попытка получить размер вызовет исключение, поэтому проверка Существует() обязательна.
ФайлНаДиске = Новый Файл("C:\Обмен\выгрузка.xml");
Если ФайлНаДиске.Существует() Тогда
РазмерВБайтах = ФайлНаДиске.Размер();
Сообщить("Размер файла: " + РазмерВБайтах + " байт");
Иначе
Сообщить("Файл не найден");
КонецЕсли;
Метод Размер() возвращает значение типа Число. Для очень больших файлов (несколько гигабайт) значение корректно обрабатывается, но при дальнейших вычислениях помните о пределах типа Число в 1С — для практических задач с файлами их достаточно.
Обратите внимание: конструктор Новый Файл(...) сам по себе не обращается к диску. Он лишь создаёт описание. Реальное обращение к файловой системе происходит при вызове Существует(), Размер() и других методов, поэтому ошибки доступа всплывают именно на этих строках.
Размер файла на клиенте и на сервере: в чём разница
Ключевой момент, который часто упускают: код, выполняемый на клиенте, видит файловую систему компьютера пользователя, а код на сервере — файловую систему сервера 1С. Если пользователь выбрал файл на своём диске, а проверку размера вы выполнили в серверной процедуре, сервер будет искать этот путь у себя и, скорее всего, не найдёт файл.
Правильный подход для тонкого и веб-клиента — сначала поместить файл во временное хранилище через НачатьПомещениеФайла или НачатьПомещениеФайлаВоВременноеХранилище, а уже потом работать с ним на сервере. Если нужно узнать размер до передачи, делайте это в клиентском контексте.
На тонком клиенте также действуют ограничения безопасности: доступ к файловой системе возможен только после интерактивного выбора файла пользователем или при подключённом расширении работы с файлами. В веб-клиенте без расширения прямой доступ к произвольным путям недоступен вовсе.
Размер нескольких файлов и каталогов через НайтиФайлы
Когда нужно узнать размеры всех файлов в папке — например, оценить объём каталога выгрузок перед архивацией — используется функция НайтиФайлы(). Она возвращает массив объектов Файл, по которому можно пройти циклом и просуммировать размеры.
НайденныеФайлы = НайтиФайлы("C:\Обмен\", "*.xml", Истина);
ОбщийРазмер = 0;
Для Каждого ТекФайл Из НайденныеФайлы Цикл
Если Не ТекФайл.ЭтоКаталог() Тогда
ОбщийРазмер = ОбщийРазмер + ТекФайл.Размер();
КонецЕсли;
КонецЦикла;
Сообщить("Суммарный размер: " + ОбщийРазмер + " байт");
Третий параметр Истина включает поиск во вложенных каталогах. Проверка ЭтоКаталог() нужна, потому что НайтиФайлы при определённых масках возвращает и сами каталоги, а у каталога метод Размер() не имеет смысла.
Учтите, что сумма размеров файлов не равна занятому месту на диске: из-за кластерной организации файловой системы реальное занятое пространство обычно больше. Для прикидки свободного места перед записью больших выгрузок суммы размеров достаточно, но для точного анализа диска такой способ не подходит.
- 1Получите путь к файлу — через диалог выбора или из настроек обмена
- 2Создайте объект Файл с этим путём
- 3Проверьте Существует() — если файла нет, сообщите пользователю и прервите операцию
- 4Вызовите Размер() и сравните с допустимым лимитом
- 5Если размер в норме — продолжайте загрузку или помещение во временное хранилище
Проверка размера перед загрузкой в базу или отправкой
Практический сценарий: перед записью файла в присоединенные файлы справочника или перед отправкой по электронной почте нужно убедиться, что он не превышает лимит. Почтовые серверы и веб-сервисы обычно ограничивают размер вложений, а хранение гигантских файлов в базе раздувает её и замедляет резервное копирование.
ФайлНаДиске = Новый Файл(ПутьКФайлу);
Если ФайлНаДиске.Существует() Тогда
МаксРазмер = 20 1024 1024; // 20 МБ
Если ФайлНаДиске.Размер() > МаксРазмер Тогда
Сообщить("Файл превышает допустимый размер 20 МБ");
Иначе
// продолжаем загрузку
КонецЕсли;
КонецЕсли;
Лимиты удобно задавать в константах или настройках обмена, а не зашивать в код. Тогда администратор сможет менять ограничение без доработки конфигурации. Для файлов, помещённых во временное хранилище, размер на сервере определяется аналогично: получаете данные из хранилища через ПолучитьИзВременногоХранилища, сохраняете во временный файл через ПолучитьИмяВременногоФайла и измеряете его.
Как представить размер в удобном виде: КБ, МБ, ГБ
Метод Размер() возвращает байты, что неудобно для пользователя: число из восьми-десяти цифр мало о чём говорит. Для отображения в сообщениях и отчётах байты принято переводить в килобайты, мегабайты или гигабайты делением на 1024.
Функция ПредставлениеРазмера(РазмерВБайтах)
Если РазмерВБайтах >= 1073741824 Тогда
Возврат Окр(РазмерВБайтах / 1073741824, 2) + " ГБ";
ИначеЕсли РазмерВБайтах >= 1048576 Тогда
Возврат Окр(РазмерВБайтах / 1048576, 2) + " МБ";
ИначеЕсли РазмерВБайтах >= 1024 Тогда
Возврат Окр(РазмерВБайтах / 1024, 1) + " КБ";
Иначе
Возврат РазмерВБайтах + " байт";
КонецЕсли;
КонецФункции
Такую функцию обычно размещают в общем модуле, чтобы использовать и в клиентских, и в серверных процедурах. Обратите внимание: в 1С традиционно используется двоичное деление (1024), а не десятичное (1000), как в маркетинговых характеристиках дисков — расхождение с показаниями Проводника Windows при этом минимально, так как Проводник тоже считает по 1024.
Размер данных в базе: присоединенные файлы и двоичные данные
Отдельная задача — узнать размер файла, уже хранящегося в информационной базе. В типовых конфигурациях присоединенные файлы хранятся либо в информационной базе (в реквизите типа ХранилищеЗначения), либо в томах на диске. В первом случае размер можно оценить, получив двоичные данные и вызвав метод Размер() у объекта ДвоичныеДанные.
ДвоичныеДанные = ХранилищеЗначения.Получить();
Если ТипЗнч(ДвоичныеДанные) = Тип("ДвоичныеДанные") Тогда
РазмерВБайтах = ДвоичныеДанные.Размер();
КонецЕсли;
Если файлы хранятся в томах на диске, размер определяется через объект Файл по пути, сформированному из настроек тома и относительного пути файла — точно так же, как в базовом сценарии. В типовых конфигурациях на БСП размер присоединенного файла часто уже хранится в реквизите справочника присоединенных файлов, и обращаться к диску вообще не требуется — достаточно прочитать реквизит.
Способы получения размера
Универсально для файлов на диске. Требует проверки Существует() и учёта контекста клиент/сервер
Для групп файлов и подсчёта объёма каталогов. Медленнее при большом числе файлов
Для данных уже в памяти или из хранилища значений. Не требует доступа к диску
Самый быстрый вариант в типовых конфигурациях — размер уже сохранён при записи файла
Типичные ошибки и как их избежать
Самая частая проблема — исключение «Файл не обнаружен» из-за вызова Размер() без проверки Существует(). Вторая по распространённости — путаница контекстов: на сервере проверяется путь, который существует только на клиенте. Третья — попытка получить размер файла, который в этот момент открыт другим процессом эксклюзивно: чтение свойств обычно возможно, но в отдельных ситуациях доступ блокируется.
Ещё одна ошибка — сравнение размера с лимитом в разных единицах: метод возвращает байты, а лимит в настройках задан в мегабайтах. Всегда приводите оба значения к одной единице перед сравнением и явно комментируйте единицу измерения в коде.
Проверка результата и границы самостоятельной работы
Чтобы убедиться, что код возвращает корректное значение, сверьте результат с размером файла в Проводнике Windows (свойства файла, поле «Размер», не «на диске»). Значения должны совпадать до байта. Если 1С показывает другое число — проверьте, тот ли файл вы открываете: относительные пути и сетевые диски, подключённые только у пользователя, частые источники путаницы.
Самостоятельная доработка кода определения размера безопасна: чтение свойств файла не изменяет ни файл, ни данные базы. Осторожность нужна только в связке с последующими операциями — удалением «лишних» файлов по размеру или очисткой каталогов. Перед такими автоматическими действиями делайте резервную копию и тестируйте логику на копии данных.
Как проверить результат
Размер совпадает со значением в свойствах файла до байта
Значение отличается — проверьте путь и контекст выполнения
Код выводит понятное сообщение и не падает
Необработанное исключение прерывает выполнение
Файл чуть меньше лимита проходит, чуть больше — блокируется
Граничные значения ведут себя непредсказуемо — проверьте единицы измерения
Частые вопросы
Можно ли узнать размер файла, не открывая его?
Да. Метод Размер() читает только атрибуты файла из файловой системы и не загружает содержимое в память. Это быстрая операция даже для файлов в несколько гигабайт.
Почему Размер() возвращает ошибку, хотя файл точно есть?
Чаще всего код выполняется не в том контексте: файл на компьютере пользователя, а проверка идёт на сервере. Также проверьте права учётной записи, под которой работает сервер 1С, и корректность пути — сетевые диски, подключённые интерактивно, серверу обычно недоступны.
Как узнать размер файла во временном хранилище?
Получите данные через ПолучитьИзВременногоХранилища() — если это ДвоичныеДанные, вызовите у них метод Размер(). Либо сохраните данные во временный файл и измерьте его через объект Файл.
Чем размер файла отличается от размера на диске?
Размер файла — это фактический объём данных в байтах, его возвращает метод Размер(). Размер на диске больше из-за выделения места целыми кластерами файловой системы. 1С штатными средствами определяет только размер файла.
Есть ли ограничение на размер файла, с которым работает 1С?
Метод Размер() корректно обрабатывает очень большие файлы. Практические ограничения возникают на других этапах: объём оперативной памяти при чтении файла целиком, лимиты веб-сервера и почтовых сервисов при передаче, настройки максимального размера данных в запросах.
Как узнать размер всех присоединенных файлов в базе?
В конфигурациях на БСП выполните запрос к справочнику присоединенных файлов с суммированием реквизита, где хранится размер. Если файлы лежат в томах на диске, пройдитесь по ним через НайтиФайлы и просуммируйте Размер() каждого файла.
Что важно запомнить
Размер файла в 1С получают через объект Файл и метод Размер() после обязательной проверки Существует(). Код выполняйте в том контексте, где файл физически доступен, для групп файлов используйте НайтиФайлы, а результат для пользователя переводите из байтов в КБ или МБ. Корректность проверяйте сверкой со свойствами файла в Проводнике.