Каждый разработчик в среде 1С рано или поздно сталкивается с ситуацией, когда программно созданный файл «исчезает» в неизвестном направлении. Вроде бы код отработал без ошибок, система бодро сообщила об успешном сохранении настроек, но на диске в ожидаемом месте файла нет. Или, что еще хуже, при переносе кода на другой компьютер или при запуске под обычным пользователем программа внезапно начинает выдавать ошибку доступа к файлу.
Давайте подробно разберем эту классическую проблему, проанализируем механизмы работы платформы 1С с файловой системой и выясним, как правильно организовывать запись и чтение файлов, чтобы раз и навсегда избежать подобных неприятностей.
Рассмотрим фрагмент кода, который часто становится источником головной боли для начинающих разработчиков:
Текст = Новый ЗаписьТекста;
Текст.Открыть("Data.txt", КодировкаТекста.ANSI);
Текст.ЗаписатьСтроку(СокрЛП(АдресСервера));
Текст.ЗаписатьСтроку(СокрЛП(ПортСервера));
Текст.ЗаписатьСтроку(СокрЛП(Пароль));
Текст.ЗаписатьСтроку(СокрЛП(Строка(Таймаут)));
Текст.Закрыть();
Сообщить("Настройки успешно сохранены!");
На первый взгляд, код абсолютно рабочий. Объект ЗаписьТекста инициализируется, открывает файл Data.txt, записывает туда параметры подключения и успешно закрывает поток. Но здесь кроется главная методологическая ошибка — использование относительного пути вместо абсолютного.
Когда мы передаем методу Открыть или конструктору объекта просто имя файла (например, "Data.txt"), платформа 1С пытается создать и записать этот файл в текущем рабочем каталоге процесса, который выполняет данный код в операционной системе.
В зависимости от режима работы и контекста выполнения этот каталог будет существенно отличаться:
C:\Program Files\1cv8\[Версия_Платформы]\bin\. Именно туда система попытается записать ваш файл.&НаСервере), рабочим каталогом становится папка службы сервера 1С:Предприятия. Чаще всего это та же папка bin на сервере или системная папка C:\Windows\System32\ (в зависимости от учетной записи, под которой запущена служба ragent).Именно поэтому при перезапуске обработки данные могут считываться корректно (ведь процесс 1С обращается к тому же своему рабочему каталогу), но сам пользователь физически не может найти этот файл на диске компьютера в привычных папках.
Рассмотрим сценарий, когда пользователь без прав администратора пытается запустить эту обработку. Программа выдает критическое исключение: Ошибка при вызове метода контекста (Открыть): Ошибка доступа к файлу 'Data.txt'.
Выясним причину этого поведения. Современные операционные системы семейства Windows (начиная с Windows Vista и выше) используют строгую политику контроля учетных записей (UAC). Системная папка C:\Program Files\ по умолчанию защищена от записи для любых программ, запущенных без явных прав администратора. Поскольку процесс 1С пытается создать файл Data.txt в своей рабочей папке bin внутри Program Files, операционная система мгновенно блокирует эту операцию из соображений безопасности.
Иногда система ведет себя еще более загадочно: ошибки не возникает, но файла в папке bin все равно нет. Это происходит из-за работы механизма виртуализации файлов VirtualStore в Windows.
Если UAC включен, но работает в режиме совместимости, операционная система перенаправляет операцию записи из защищенной папки Program Files в специальный изолированный каталог пользователя:
C:\Users\[Имя_Пользователя]\AppData\Local\VirtualStore\Program Files\1cv8\[Версия_Платформы]\bin\
Для программы все выглядит так, будто файл успешно создался в рабочей папке. Однако:
Попутно разберем важное технологическое различие между объектами работы с текстом в 1С. Начинающие разработчики часто путают логику работы объектов ЗаписьТекста и ТекстовыйДокумент.
При использовании ТекстовыйДокумент данные накапливаются в оперативной памяти компьютера, и физическая запись на диск происходит только в момент явного вызова метода Записать(ПутьКФайлу). В случае с ЗаписьТекста мы работаем напрямую с потоком вывода. Файл создается и блокируется операционной системой сразу в момент вызова метода Открыть() (или при инициализации конструктора), а запись строк происходит порционно. Окончательный сброс буфера на диск и освобождение файла происходят при вызове метода Закрыть().
Использование относительных путей при работе с файлами в 1С — это грубая ошибка проектирования. Чтобы гарантировать стабильную работу конфигурации в любых условиях (на клиенте, на сервере, под любыми правами), необходимо всегда явно формировать **абсолютные пути**.
Рассмотрим три надежных сценария работы.
Если файл нужен вам только временно (например, для передачи данных во внешнюю утилиту или для промежуточного хранения в рамках текущего сеанса), используйте системный каталог временных файлов. У текущего пользователя операционной системы всегда есть полные права на чтение и запись в эту директорию.
Реализуем это на практике:
// Формируем абсолютный путь во временном каталоге пользователя
ИмяФайла = КаталогВременныхФайлов() + "Data.txt";
Текст = Новый ЗаписьТекста;
Текст.Открыть(ИмяФайла, КодировкаТекста.ANSI);
Текст.ЗаписатьСтроку(СокрЛП(АдресСервера));
Текст.ЗаписатьСтроку(СокрЛП(ПортСервера));
Текст.ЗаписатьСтроку(СокрЛП(Пароль));
Текст.ЗаписатьСтроку(СокрЛП(Строка(Таймаут)));
Текст.Закрыть();
Сообщить("Файл успешно сохранен по пути: " + ИмяФайла);
Также для генерации уникальных имен временных файлов отлично подходит встроенный метод ПолучитьИмяВременногоФайла(). Он автоматически создает уникальное имя файла с нужным расширением в системной временной папке:
ПутьКВременномуФайлу = ПолучитьИмяВременногоФайла("txt");
// Теперь переменная ПутьКВременномуФайлу содержит полный путь, например:
// C:\Users\User\AppData\Local\Temp\v8_D3F4_32.txt
Если файлы настроек должны сохраняться на постоянной основе и пользователь должен иметь к ним прямой доступ через проводник, идеальным выбором будет стандартный каталог документов пользователя. Для его получения в 1С используется метод КаталогДокументов() (соответствует папке "Мои документы" в Windows):
ИмяФайла = КаталогДокументов() + "НастройкиПодключения.txt";
Текст = Новый ЗаписьТекста;
Текст.Открыть(ИмяФайла, КодировкаТекста.ANSI);
Текст.ЗаписатьСтроку(СокрЛП(АдресСервера));
Текст.ЗаписатьСтроку(СокрЛП(ПортСервера));
Текст.ЗаписатьСтроку(СокрЛП(Пароль));
Текст.ЗаписатьСтроку(СокрЛП(Строка(Таймаут)));
Текст.Закрыть();
Сообщить("Настройки сохранены в Ваши документы: " + ИмяФайла);
Если вы работаете в современной типовой конфигурации 1С, настоятельно рекомендуется использовать готовые инструменты БСП. Общие модули библиотеки содержат готовые кроссплатформенные функции для работы с файловой системой, которые автоматически учитывают особенности операционных систем (Windows или Linux) и разграничение прав доступа клиентского и серверного контекстов. Обратите внимание на функции общего модуля ФайловыеФункцииКлиентСервер.
Подведем итог: никогда не полагайтесь на поведение операционной системы по умолчанию. Явное указание абсолютных путей с использованием встроенных функций платформы КаталогВременныхФайлов(), КаталогДокументов() или методов БСП гарантирует, что ваши файлы никогда не потеряются, а пользователи не столкнутся с неожиданными ошибками прав доступа.