【发布时间】:2013-07-15 23:00:27
【问题描述】:
我有一个代码,如果从 emacs 中的 slime 提示符执行,则运行时没有错误。如果我从提示符启动 sbcl,则会收到错误消息:
* (ei:proc-file "BRAvESP000.log" "lixo")
debugger invoked on a SB-INT:STREAM-ENCODING-ERROR:
:UTF-8 stream encoding error on
#<SB-SYS:FD-STREAM for "file /Users/arademaker/work/IBM/scolapp/lixo"
{10049E8FF3}>:
the character with code 55357 cannot be encoded.
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [OUTPUT-NOTHING ] Skip output of this character.
1: [OUTPUT-REPLACEMENT] Output replacement string.
2: [ABORT ] Exit debugger, returning to top level.
(SB-IMPL::STREAM-ENCODING-ERROR-AND-HANDLE #<SB-SYS:FD-STREAM for "file /Users/arademaker/work/IBM/scolapp/lixo" {10049E8FF3}> 55357)
0]
问题在于,在这两种情况下,我都使用相同的 sbcl 1.1.8 和同一台机器,Mac OS 10.8.4。任何的想法?
代码:
(defun proc-file (filein fileout &key (fn-convert #'identity))
(with-open-file (fout fileout
:direction :output
:if-exists :supersede
:external-format :utf8)
(with-open-file (fin filein :external-format :utf8)
(loop for line = (read-line fin nil)
while line
do
(handler-case
(let* ((line (ppcre:regex-replace "^.*{jsonTweet=" line "{\"jsonTweet\":"))
(data (gethash "jsonTweet" (yason:parse line))))
(yason:encode (funcall fn-convert (yason:parse data)) fout)
(format fout "~%"))
(end-of-file ()
(format *standard-output* "Error[~a]: ~a~%" filein line)))))))
【问题讨论】:
-
我建议您首先假设这不是 yason 问题——我们会很快找出是否是——然后将以下内容添加到您的代码中:
(format *standard-output* "~&~{~x~^ ~}" (map 'list 'char-code line))。失败情况下的最后一行是否与 SLIME 环境中对应的行相同? -
可能在多个目录中存在名为 BRAvESP000.log 的文件,如果您在 SLIME 中或手动启动 SBCL,则当前目录会有所不同。尝试绝对路径。
-
如果字符代码没有错误,则属于代理对的Unicode范围。这些不是 UTF-8 编码的字符,它们保留用于 UTF-16。这是我的猜测:网页设计中有一个现代传统,即使用私人平面字符和特殊字体作为图标(如各种箭头、子弹等)。 Twitter 尤其如此(例如 Github 也是如此)。这是 HTML 页面节省加载图像的一种方式(因为这些是特殊字体的矢量轮廓)。我想 Emacs 在发送之前会处理它们。
-
但 SBCL 本身没有。我认为如果你只是删除那些,或者用不那么冒犯的东西代替,你会没事的。
标签: unicode utf-8 lisp common-lisp sbcl