我有点矢量 - #*10010010001001...
我想使用READ-BYTE从向量中读取八位字节。 但它需要一个二进制流对象。
我似乎无法弄清楚如何做到这一点。我尝试使用WRITE-SEQUENCE从一个简单的向量(从位向量转换)中获取一个新流:
(WRITE-SEQUENCE (map 'array #'identity #*10010010...) *standard-output*)
但它抱怨需要CHARACTER的预期类型。
(我正在使用Clozure Common Lisp。)
我做错了什么?
(请不要将灵活流作为答案。我不打算为一件小事添加一个全新的库。)
答案 0 :(得分:4)
您可以使用非标准Gray Streams扩展来定义自己的流类。 octet向量的一个简单示例(我使用SBCL,但CCL也应支持Gray Streams):
(deftype octet () '(unsigned-byte 8))
(defclass octet-input-stream (fundamental-binary-input-stream)
((data :initarg :data :type (vector octet))
(position :initform 0)))
(defmethod stream-element-type ((stream octet-input-stream))
'octet)
(defmethod stream-read-byte ((stream octet-input-stream))
(with-slots (data position) stream
(if (< position (length data))
(prog1 (aref data position)
(incf position))
:eof)))
(let* ((arr (make-array 3 :element-type 'octet :initial-contents '(50 100 150)))
(stream (make-instance 'octet-input-stream :data arr)))
(loop for octet = (read-byte stream nil nil)
while octet
do (format t "~8,'0b~%" octet)))
; 00110010
; 01100100
; 10010110
关于需要屏蔽位的注释,标准中有bit-wise operators。
(logior 50 #b00001000)
;=> 58
对于八位字节向量的打印表示,您可以定义自己漂亮的打印机调度功能:
(defun print-octets (stream vector)
(write-string "#<octet vector:" stream)
(pprint-newline :mandatory stream)
(loop for octet across vector
do (format stream "~8,'0b " octet)
(pprint-newline :fill stream))
(pprint-newline :mandatory stream)
(write-string ">" stream))
CL-USER> (set-pprint-dispatch '(vector (unsigned-byte 8)) #'print-octets)
CL-USER> (make-array 20 :element-type 'octet :initial-contents '(54 123 67 34 65 65 23 98
67 23 54 12 76 123 230 65
23 87 49 10))
#<octet vector:
00110110 01111011 01000011 00100010 01000001 01000001 00010111 01100010
01000011 00010111 00110110 00001100 01001100 01111011 11100110 01000001
00010111 01010111 00110001 00001010
>