我试图将一些C代码移植到Common Lisp(细节可能无关紧要,但我试图将rgb图像文件读入内存块以绑定纹理以便与cl-opengl一起使用)。我试图做的C版本是:
void * data;
FILE * file;
int bytecount = width * height * 3;
file = fopen ( rgbfilepath, "rb" );
data = malloc( bytecount );
fread( data, bytecount, file);
fclose( file );
//do stuff with data...
我这样做已经有几年了,但是我对这段代码的理解是,它正在从文件中读取一堆字节到malloc
内存中而没有对内容进行任何关注那些字节。
经过一些谷歌搜索,我发现http://rosettacode.org/wiki/Read_entire_file#Common_Lisp和http://www.codecodex.com/wiki/Read_a_file_into_a_byte_array#Common_Lisp非常相似。我的版本看起来像
(with-open-file (stream rgb-file-path)
(let ((data (make-string (file-length stream)))
(read-sequence data stream)
;;do stuff with data...
当我在rgb文件上运行此内容时,我收到SBCL的以下投诉:
debugger invoked on a SB-INT:STREAM-DECODING-ERROR in thread
#<THREAD "main thread" RUNNING {10055E6EA3}>:
:UTF-8 stream decoding error on
#<SB-SYS:FD-STREAM
for "file /home/john/code/lisp/commonlisp/opengl-practice/wall.rgb"
{1005A8EB53}>:
the octet sequence #(218 0) cannot be decoded.
我对此的推测性解释是make-string
的使用期望字节是字符,而我加载的rgb文件只有一堆字节,不一定是有效的ASCII或预期的任何字符集。但我可能会离开。有关如何复制fread()
的内容的任何建议吗?
提前致谢!
答案 0 :(得分:0)
如果你真的想要这样做,你需要指定element-type
到open
(或with-open-file
)这是integer
的子类型(很可能是某种东西)与'(unsigned-byte 8)
类似,因此它被读作八位字节而不是字符。
opticl
,它非常简单,使用二维或三维简单数组来表示图像数据(两个维度加一个颜色)。
答案 1 :(得分:0)
非常感谢Svante带领我朝着正确的方向前进。这是有用的:
(setf mystream (open rgb-file-name :direction :input :element-type '(unsigned-byte 8)))
(setf data (make-array (file-length mystream) :element-type '(unsigned-byte 8)))
(read-sequence data mystream)
(close mystream)