Файл только для чтения?

Понадобилось мне тут определить, является ли файл "только для чтения". Я помню про функцию vl-file-systime, но иногда ее недостаточно...

Файл для лиспа может быть "ReadOnly" в двух случаях - либо файл открыт каким-либо приложением, либо у него выставлено свойство "ReadOnly". Вариант с настройками прав доступа пока не рассматриваем. Как разрулить эту ситуацию, пока не представляю.

Если файл открыт каким-либо приложением, то вызов функции vl-file-systime вернет nil. Можете попробовать: сохранить текущий файл как c:\1.dwg, например, открыть новую сессию AutoCAD и в ней выполнить

1
(vl-file-systime "c:\\1.dwg")

В результате получите nil.

Если файл закрыть, то тот же код вернет список (за подробностями отправляю в справку ;))

А если файл закрыт, но ему установлен атрибут ReadOnly? Поможет наш люто любимый Scripting.FileSystemObject:

1
(setq svr (vlax-get-or-create-object "Scripting.FileSystemObject"))

Если его просмотреть, увидим метод GetFile с единственным параметром (именем файла):

1
(setq obj (vlax-invoke-method svr 'getfile file-name))

Просматриваем через vlax-dump-object уже этот объект и обнаруживаем в нем свойство Attributes. Свойство имеет числовое значение, вычисляемое как сумма следующих битов:

Значение Имя
0 Normal
1 ReadOnly
2 Hidden
4 System
8 Volume (имя диска)
16 Directory (каталог)
32 Archive (установлено свойство "Архивный")
64 Alias (ярлык)
2048 Compressed

Поскольку в данный момент нас интересует только свойство ReadOnly, проверяем атрибут на четность - и вуаля, все готово! :) Проверку на наличие файла делать не будем - лишнее.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
(defun _lispru-is-file-read-only (file-name / file_hangle res)
                                 ;|
*    Проверяет, является ли файл "read-only". Возвращает t, если да. Проверки
* наличия файла не выполняется.
*    Параметры вызова:
* file-name полное имя файла, с путем.
(_lispru-is-file-read-only "Z:\\Test\\Молниезащита.dwg")
|;

  (or (not (vl-file-systime file-name))
      ((lambda (/ svr obj res)
         (setq svr (vlax-get-or-create-object "Scripting.FileSystemObject")
               obj (vlax-invoke-method svr 'getfile file-name)
               res (vlax-get-property obj 'attributes)
               ) ;_ end of setq
         (vlax-release-object obj)
         (vlax-release-object svr)
         (setq obj nil
               svr nil
               ) ;_ end of setq
         (/= (* 2 (/ res 2)) res)
         ) ;_ end of lambda
       )
      ) ;_ end of or
  ) ;_ end of defun

Исходник можно забрать тут.



Поделитесь своим мнением


Я не робот.