пятница, 22 ноября 2013 г.

Кое-что о DWL и DWL2 файлах

Файлы с расширением DWL и DWL2 автоматически создаются AutoCAD'ом и, как пишет Александр Ривилис:
Оба файла используются для блокировки одновременного доступа к файлу и содержат информацию с какого PC и каким пользователем и в какое время открыт dwg-файл. dwl-файл содержит информацию в текстовом виде, а dwl2-файл в виде xml.
 Эти файлы исчезают при закрытии AutoCAD, если его работа не была завершена аварийно. Однако есть один нюанс, который может быть интересен для .NET-программистов...

Дело в том, что "время жизни" файлов DWL и DWL определяется "временем жизни" объекта Database. Что из этого следует? Это значит, что если по завершению работы с Database вы забываете вызвать Dispose(), то могут проявиться неприятные последствия этого... Приведу наглядный пример.

 Предположим, что нам нужно программно выполнить некоторый набор действий, а именно:
  1. Требуется программно сгенерировать набор чертежей (DWG файлов).
  2. Запустить стороннее внешнее приложение (EXE файл), передав ему информацию о том, куда мы сохранили сгенерированные чертежи.
  3. Внешнее приложение выполняет какой-то набор действий, на основе наших чертежей, после чего должно очистить содержимое каталога, в который мы положили временные чертежи, т. к. они более не нужны, а захламлять компьютер ненужными файлами - это плохая идея.  

После того, как вы создадите временный экземпляр Database, поработаете с ним программно и затем сохраните результат в DWG файл, без открытия этого файла в AutoCAD (т. е. не создавая объект Document), то возле DWG файла появятся и одноимённые DWL\DWL2 файлы. 

Сгенерированные чертежи можно открыть с любого компьютера и отредактировать их, либо просто переименовать - файлы DWL\DWL2 не воспрепятствуют этому, т. к. DWG пока никем не открыт в AutoCAD.

Когда внешняя программа в п.3 приступит к удалению содержимого каталога, эта операция может завершиться неудачно, если в каталоге будут присутствовать файлы DWL\DWL2, поскольку в случае их наличия, ваш AutoCAD блокирует эти файлы от стороннего изменения\переименования\удаления. 

По какой причине возле сгенерированных нами DWG файлов могут появиться файлы DWL\DWL2? Они появятся в том случае, если ваш код будет выглядеть примерно так:

   1:  /// <summary>
   2:  /// Create the new drawing and save him to the file.
   3:  /// </summary>
   4:  /// <param name="file_name">File's full name.</param>
   5:  void CreateNewDrawing(String file_name) {
   6:      Db.Database db = new Db.Database(true, true);
   7:   
   8:      // do something...
   9:   
  10:      // now save result into the file.
  11:      db.SaveAs(file_name, Db.DwgVersion.Current);
  12:  }

Дело в том, что в данном коде, по выходе из метода CreateNewDrawing не происходит  автоматическое освобождение ресурсов, использовавшихся нашим объектом Database. Эти ресурсы теперь будут освобождены либо при закрытии AutoCAD, либо в процессе его работы, но позднее, когда по мере необходимости запустится внутренний механизм очистки неиспользуемых ресурсов - только после этого из каталога исчезнут DWL\DWL2 файлы.

Всё, что от нас требуется для того, чтобы исправить эту ситуацию - это принудительно освободить ресурсы, используемые нашим объектом Database, когда он нам более не нужен. Поскольку Database реализовывает интерфейс IDisposable, то решение очевидно - нужно им воспользоваться:

   1:  /// <summary>
   2:  /// Create the new drawing and save him to the file.
   3:  /// </summary>
   4:  /// <param name="file_name">File's full name.</param>
   5:  void CreateNewDrawing(String file_name) {
   6:      using (Db.Database db = new Db.Database(true, true)) {
   7:   
   8:          // do something...
   9:   
  10:          // now save result into the file.
  11:          db.SaveAs(file_name, Db.DwgVersion.Current);
  12:      }
  13:  }

Такой код предотвращает появление файлов DWL\DWL2 возле сгенерированных нами чертежей и очистка каталога, указанная в п. 3 теперь будет проходить успешно.

Вообще, на тему "AutoCAD & IDisposable" обязательно следует почитать здесь.

Комментариев нет: