如何在Common Lisp中创建双向二进制流?

时间:2019-07-02 13:13:30

标签: lisp common-lisp

我读了How to create a binary stream (not a file) in Common Lisp?,它描述了如何创建二进制流而不是双向流。我尝试使用引用的库自己执行此操作,但失败了。我的尝试如下:

(defun make-test-binary-stream ()
  (make-two-way-stream (flexi-streams:make-in-memory-input-stream 
                         (vector))
   (flexi-streams:make-in-memory-output-stream)))

我像这样使用它

(let ((str (make-test-binary-stream))) 
   (lisp-binary:write-float :double 123.45d0 :stream str) 
   (lisp-binary:read-binary-type 'double-float str))

我期望的结果是123.45d0,但是它返回0.0d0

如何创建行为符合预期的二进制流,从而允许我在其中写入一个值,然后再读取相同的值?我想要这样的流来测试将流作为流的输入和输出的编码和解码功能的正确性。

1 个答案:

答案 0 :(得分:2)

双向流S是一对(I,O),其中I是输入流,O是输出流。这两个流不一定相关,仅表示当您从S读取时,您从I读取,并且当您写入S时,您也写入了O

在这里,您尝试读取由空序列支持的内存流。流只是按顺序提供项目,而是流。在这里,流立即到达文件结尾。

匿名缓冲区

没有直接回答问题,但是有时我会使用 lisp-binary ,而我的测试方法如下:

(with-input-from-sequence 
    (in (with-output-to-sequence (out)
          (write-float :double 123.45d0 :stream out)))
  (read-binary-type 'double-float in))

让我们分解:

(flex:with-output-to-sequence (out)
  (write-float :double 123.45d0 :stream out))

以上将out本地绑定到写入隐藏的内存中序列的流,并最终返回该序列。整个表达式返回一个字节缓冲区:

#(205 204 204 204 204 220 94 64)

此缓冲区被分配给with-input-from-sequence,以将in绑定到从该序列读取数据的本地流。 read-binary-type使用该输入流对值进行解码。

临时文件

(defpackage :so (:use :cl :lisp-binary :flexi-streams :osicat))
(in-package :so)

osicat 系统具有一个宏,可以在输入和输出模式下打开一个临时文件:

(with-temporary-file (io :element-type '(unsigned-byte 8))
  (write-float :double pi :stream io)
  (file-position io 0)
  (read-binary-type 'double-float io))

在内存循环缓冲区中

我找不到在同一个向量之间读写的内存I / O流的现有实现;您可以使用两个共享内部向量的 flexi-stream 破解某些东西(但这很危险,在某些情况下会破坏数据一致性),或者使用灰度流构建一个东西。另请参见cl-stream