1

在这个问题之后:调用加载时文件规范中的奇怪符号我用路径名尝试了运气,但是,如您所见,失败了。以下是错误的示例,我无法解释:

此代码不起作用:

(defun test-process-imgae-raw ()
  (cl-gd:with-image-from-file
      (test #P"digit-recognition:digit-7.png")
    (process-image-raw test)))

这也不是:

(defun test-process-imgae-raw ()
  (cl-gd:with-image-from-file
      (test "digit-recognition:digit-7.png")
    (process-image-raw test)))

但是这段代码确实:

(defun test-process-imgae-raw ()
  (cl-gd:with-image-from-file
      (test (translate-logical-pathname "digit-recognition:digit-7.png"))
    (process-image-raw test)))

这也是如此:

(defun test-process-imgae-raw ()
  (cl-gd:with-image-from-file
      (test (translate-logical-pathname #P"digit-recognition:digit-7.png"))
    (process-image-raw test)))

这是“翻译”:

(setf (logical-pathname-translations "DIGIT-RECOGNITION")
      `(("**;*.*" "/home/wvxvw/Projects/digit-recognition/**/*.*")))

这是我得到的错误:

Pathname components from SOURCE and FROM args to TRANSLATE-PATHNAME
did not match:
  :NEWEST NIL
   [Condition of type SIMPLE-ERROR]

Restarts:
 0: [RETRY] Retry SLIME REPL evaluation request.
 1: [*ABORT] Return to SLIME's top level.
 2: [ABORT] Abort thread (#<THREAD "repl-thread" RUNNING {1003800113}>)

Backtrace:
  0: (SB-IMPL::DIDNT-MATCH-ERROR :NEWEST NIL)
  1: (SB-IMPL::TRANSLATE-COMPONENT :NEWEST NIL :NEWEST T)
  2: (TRANSLATE-PATHNAME #P"DIGIT-RECOGNITION:DIGIT-7.PNG.NEWEST" #P"DIGIT-RECOGNITION:**;*.*" #P"/home/wvxvw/Projects/digit-recognition/**/*.*")
  3: (TRANSLATE-LOGICAL-PATHNAME #P"DIGIT-RECOGNITION:DIGIT-7.PNG.NEWEST")
  4: (SB-IMPL::QUERY-FILE-SYSTEM #P"DIGIT-RECOGNITION:DIGIT-7.PNG" :TRUENAME NIL)
  5: (PROBE-FILE #P"DIGIT-RECOGNITION:DIGIT-7.PNG")
  6: (CREATE-IMAGE-FROM-FILE #<unavailable argument> NIL)
  7: (TEST-PROCESS-IMGAE-RAW)

我正在尝试阅读有关 translate-pathname 的 Hyperspec 部分,但我完全无法理解它所说的内容,无论是从它显示的示例中。更不用说它了,我什至无法理解,如果你按照你制定的任何规则来转换一个字符串,怎么可能会出错,到目前为止,这只是一种方式的转换......

我正在尝试阅读此功能的 SBCL 源代码,但它们确实很长,并且尝试以这种方式找出问题需要花费大量时间。

tl; drtranslate-logical-pathname如果从系统代码调用,从用户代码调用会产生与从该函数产生的结果不同的东西怎么可能?这不仅是不可移植的,而且完全被破坏了。

编辑:

在左侧的模式中添加一个星号,但在右侧没有解决这个问题。但是为什么这是必要的目的或逻辑超出了我的范围。

IE

(setf (logical-pathname-translations "DIGIT-RECOGNITION")
      `(("**;*.*.*" "/home/wvxvw/Projects/digit-recognition/**/*.*")))

这允许路径名喜欢digit-recognition:foo.bar.newest成功,就像digit-recognition:foo.bar但为什么那个星号要求超出我的范围。另外,为什么系统函数感觉有权将路径名更改为给出的其他名称?.. 但只是为了不让您感到困惑,with-image-from-file仅适用于已经扩展的路径translate-logical-pathname,否则将无法正常工作。

编辑2:

好的,这似乎是 的问题cl-gd,而不是尝试扩展文件名,而是从字面上理解。这段代码create-image-from-file可能最好地回答了我的问题:

(when (pathnamep file-name)
  (setq file-name
          #+:cmu (ext:unix-namestring file-name)
          #-:cmu (namestring file-name)))
(with-foreign-object (err :int)
  (with-cstring (c-file-name file-name)
    (let ((image (ecase %type
                   ((:jpg :jpeg)
                     (gd-image-create-from-jpeg-file c-file-name err))

即而不是做(namestring file-name)它必须做(namestring (trnaslate-logical-pathname file-name))。呃...

4

1 回答 1

1

另一种方法是使用TRUENAME,它返回真实的文件名。通常这不会有什么不同。

映像具有文件版本的文件系统(如 VMS 的文件系统,...)。如果您有一个逻辑路径名foo:bar;baz.png.newest,那么它可能会转换为,例如/myfiles/images/baz.png~newest(再次假设它具有版本号)。这仍然不是一个真正的物理文件。如果这样的 Lisp 系统试图打开文件,它必须查看文件系统以实际确定最新的文件。那可能是/myfiles/images/baz.png~42

因此,如果您想将真实的物理文件名传递给外部工具(如 C 库),扩展逻辑路径名可能不够,但可能需要计算真实名称- 真实的物理文件。

处理文件版本的能力来自于文件版本在ITS、VMS 或各种 Lisp Machine 操作系统等操作系统中非常普遍的时代(请参阅版本控制文件系统)。

主要的实际问题是,对于各种 CL 实现,没有用于路径名操作的通用测试套件,因此实现在许多细微的细节上存在差异(尤其是当您需要处理来自不同操作系统的不同文件系统时)。另外,真实的文件系统有复杂性——例如,Mac OS X 中的文件名在处理变音符号时使用特殊的 unicode 编码。

于 2012-12-28T13:58:25.383 回答