translate-pathname表现得很奇怪

时间:2012-12-28 12:34:15

标签: common-lisp

关注这个问题:Strange symbols in filespec when calling load我试着用路径名运气,但是,如你所见,失败了。下面是一个错误的例子,我无法解释:

此代码不起作用:

(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; dr 如果从系统代码调用,从用户代码调用的translate-logical-pathname如何生成与该函数生成的内容不同的内容?这不仅是非便携式的,而且完全被打破了。

修改

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

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

这允许像digit-recognition:foo.bar.newest这样的路径名成功,就像digit-recognition:foo.bar一样,但为什么星号的要求超出了我的要求。另外,为什么系统函数有权将路径名更改为其他内容?...但是为了不让您感到困惑,with-image-from-file仅适用于已经由{{1}扩展的路径},否则无效。

EDIT2:

好吧,好像这是translate-logical-pathname的问题,而不是尝试扩展文件名,而是从字面上理解它。从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)。咄...

1 个答案:

答案 0 :(得分:0)

另一种方法是使用TRUENAME,它返回真实的文件名。通常这不会产生任何影响。

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

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

处理文件版本的能力来自文件版本的时间,这些版本很常见(参见Versioning file system)与ITS,VMS或各种Lisp Machine操作系统等操作系统。

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