[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: probe-file & file-write-date redundancy?

>I have an application that is comparing file dates of several hundred files in
>each of ~6 directories.  since this is a test that is being performed 
>while a user is waiting to check on status of process steps (determining which
>files to update or create), I'd like it to be reasonably fast.
>currently, to be on the safe side, I usually do:
>(defun FILE-WRITE-DATE-OR-NIL (file-string)
>  (let ((path (pathname file-string)))
>    (and (probe-file path) (file-write-date path))
>    ))
>however, file-write-date is doing some kind of probe test since if the file
>doesn't exist, it generates an error. I was wondering whether there was an
>intermediate write-date function in MCL that someone knows of I could call that
>would return a NIL instead of generate an error when the file doesn't exist and
>thus eliminate the redundant probe-file checking that I'm doing.

The following is about as fast as you can get. It saves time by returning
the date in Mac format rather than as a Common Lisp universal time.
You can convert between mac & universal times with the functions
ccl:: mac-to-universal-time & ccl::universal-to-mac-time.

(eval-when (:compile-toplevel :execute)
  (defconstant ccl::$iopbsize (record-length :hParamBlockRec))
  (defconstant ccl::$iofilename (get-field-offset :hParamBlockRec.ioNamePtr)))

(defun mac-file-mod-date-or-nil (path)
  (ccl::%stack-iopb (pb np)
    (when (eql 0 (ccl::%path-to-iopb path pb nil))
      (%get-unsigned-long pb (get-field-offset :hParamBlockRec.ioFlMdDat)))))

; MCL's file-write-date could be implemented as follows:

(defun my-file-write-date (path)
  (let ((mac-date (mac-file-mod-date-or-nil path)))
    (unless mac-date
      (error "File not found: ~s" path))
    (ccl::mac-to-universal-time mac-date)))

Disclaimer: The above code uses undocumented internals of the MCL
implementation. It may cease to work without warning in future versions
of MCL. Jeffrey Kane's code is more portable, but will probably be a little
bit slower.