在 MacBook 中使用 Common Lisp 创建名称中带有方括号的文件会产生问题。我该怎么办?

问题描述 投票:0回答:1

我正在尝试将一些用于读取/写入 xlsx 文件的 Racket 包转换为 Common Lisp,但遇到了问题。 Excel 文件只不过是一束具有严格规范的压缩 xml 文件。 其中有一个

[Content_type].xml
[Content_Type].xml
文件。 尝试在 MacBook 中生成并写入名称中带有方括号的文件会生成错误:

(defparameter *zip-xlsx-temp-directory* "test-directory/")
(defparameter *content-type-file* (merge-pathnames "[Content_Types].xml" *zip-xlsx-temp-directory*))
(with-open-file (stream (ensure-directories-exist *content-type-file-1*)
                        :direction :output
                        :if-does-not-exist :create
                        :if-exists :supersede)
  (format stream ""))

bad place for a wild pathname
   [Condition of type SB-INT:SIMPLE-FILE-ERROR]

Restarts:
 0: [RETRY] Retry SLY interactive evaluation request.
 1: [*ABORT] Return to SLY's top level.
 2: [ABORT] abort thread (#<THREAD tid=11295 "slynk-worker" RUNNING {70073BBFC3}>)

Backtrace:
 0: (SB-KERNEL::%FILE-ERROR #P"test-directory/[Content_Types].xml" "bad place for a wild pathname")
      Locals:
        ARGUMENTS = NIL
        DATUM = "bad place for a wild pathname"
        PATHNAME = #P"test-directory/[Content_Types].xml"
 1: (ENSURE-DIRECTORIES-EXIST #P"test-directory/[Content_Types].xml" :VERBOSE T :MODE 511)
      Locals:
        #:.DEFAULTING-TEMP. = T
        #:.DEFAULTING-TEMP.#1 = 511
        SB-IMPL::CREATED-P = NIL
        PATHNAME = #P"/Users/josephus/.roswell/local-projects/cl-simple-xlsx/tests/test-directory/[Content_Types].xml"
        SB-IMPL::PATHSPEC = #P"test-directory/[Content_Types].xml"
 2: ((LAMBDA ()))
 3: (SB-INT:SIMPLE-EVAL-IN-LEXENV (WITH-OPEN-FILE (STREAM (ENSURE-DIRECTORIES-EXIST *CONTENT-TYPE-FILE-1* :VERBOSE T) :DIRECTION :OUTPUT :IF-DOES-NOT-EXIST :CREATE ...) (FORMAT STREAM "")) #<NULL-LEXENV>)
 4: (EVAL (WITH-OPEN-FILE (STREAM (ENSURE-DIRECTORIES-EXIST *CONTENT-TYPE-FILE-1* :VERBOSE T) :DIRECTION :OUTPUT :IF-DOES-NOT-EXIST :CREATE ...) (FORMAT STREAM "")))
 5: ((LAMBDA NIL :IN SLYNK:INTERACTIVE-EVAL))
 6: (SLYNK::CALL-WITH-RETRY-RESTART "Retry SLY interactive evaluation request." #<FUNCTION (LAMBDA NIL :IN SLYNK:INTERACTIVE-EVAL) {70073E8F3B}>)
 7: (SLYNK::CALL-WITH-BUFFER-SYNTAX NIL NIL #<FUNCTION (LAMBDA NIL :IN SLYNK:INTERACTIVE-EVAL) {70073E8F1B}>)
 8: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SLYNK:INTERACTIVE-EVAL "(with-open-file (stream (ensure-directories-exist *content-type-file-1* :verbose t) ..)
 9: (EVAL (SLYNK:INTERACTIVE-EVAL "(with-open-file (stream (ensure-directories-exist *content-type-file-1* :verbose t) ..)
10: (SLYNK:EVAL-FOR-EMACS (SLYNK:INTERACTIVE-EVAL "(with-open-file (stream (ensure-directories-exist *content-type-file-1* :verbose t) ..)
11: ((LAMBDA NIL :IN SLYNK::SPAWN-WORKER-THREAD))
12: (SLYNK-SBCL::CALL-WITH-BREAK-HOOK #<FUNCTION SLYNK:SLYNK-DEBUGGER-HOOK> #<FUNCTION (LAMBDA NIL :IN SLYNK::SPAWN-WORKER-THREAD) {70073E8C6B}>)
13: ((FLET SLYNK-BACKEND:CALL-WITH-DEBUGGER-HOOK :IN "/Users/josephus/.roswell/lisp/sly/git/slynk/backend/sbcl.lisp") #<FUNCTION SLYNK:SLYNK-DEBUGGER-HOOK> #<FUNCTION (LAMBDA NIL :IN SLYNK::SPAWN-WORKER-T..
14: ((LAMBDA NIL :IN SLYNK::CALL-WITH-LISTENER))
15: (SLYNK::CALL-WITH-BINDINGS ((*PACKAGE* . #<PACKAGE "CL-SIMPLE-XLSX/TESTS/MAIN">) (*DEFAULT-PATHNAME-DEFAULTS* . #P"/Users/josephus/.roswell/local-projects/cl-simple-xlsx/tests/") (* . #1="+01:00") (**..
16: ((LAMBDA NIL :IN SLYNK::SPAWN-WORKER-THREAD))
17: ((FLET SB-UNIX::BODY :IN SB-THREAD::RUN))
18: ((FLET "WITHOUT-INTERRUPTS-BODY-" :IN SB-THREAD::RUN))
19: ((FLET SB-UNIX::BODY :IN SB-THREAD::RUN))
20: ((FLET "WITHOUT-INTERRUPTS-BODY-" :IN SB-THREAD::RUN))
21: (SB-THREAD::RUN)

这似乎是 Lisp 固有的问题。

使用我的 Python(在 ipython zshell 中)并执行以下操作:

with open("[Content_Types].xml", "w") as f:
    f.write("<H1>Hi</H1>")

工作没有错误。

我尝试了 (truename path) 或转义名称“[Content_Types].xml”或“\[Content_Types\].xml”中的括号 - 如果转义第一个似乎是正确的。但这没有帮助。仍然出现错误的通配符错误。

excel xml file lisp common-lisp
1个回答
0
投票

写完之后,我尝试在Linux(Ubuntu)中重现它,然后查阅了ChatGPT。它最初的答案(使用

truename
并转义括号是错误的)。 所以我认为其他人在直接询问 ChatGPT 时可能也会遇到这个问题。

解决方案是:

如果您必须在 macOS 上的 Common Lisp 中使用带括号的文件名(例如,[Content_Types].xml),请务必确保在处理文件操作时正确处理这些括号。具体方法如下:

在 Common Lisp 中处理带括号的文件名:

1.  Use make-pathname to create pathnames:
This can avoid issues with special characters.
(defparameter *content-type-file*
  (make-pathname :directory content-dir :name "[Content_Types]" :type "xml"))
2.  Pass the pathname directly to with-open-file:
;; so I did first:
(defparameter *content-dir* "/Users/<your-user-name>/Downloads/test-zip/")
(ensure-directories-exist *content-dir*)
(defparameter *content-type-file*
  (make-pathname :directory *content-dir* :name "[Content_Types]" :type "xml"))

;; and then - step 2:
(with-open-file (stream *content-type-file*
                        :direction :output
                        :if-exists :supersede
                        :if-does-not-exist :create)
  (format stream "<H1/>"))

;; => NIL

然后它正确创建了名称中带有方括号的文件。

© www.soinside.com 2019 - 2024. All rights reserved.