lisp - 如何在 Common Lisp 中创建双向二进制流?
问题描述
我阅读了如何在 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
。
我怎样才能创建一个行为如我所料的二进制流,允许我写入一个值然后读回相同的值?我想要这样一个流来测试将流作为输入和输出到流的编码和解码函数的正确性。
解决方案
双向流是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 流的现有实现;您可以使用两个共享内部向量的弹性流来破解某些东西(但这很危险,在某些情况下数据一致性会中断),或者从灰色流构建一个;另请参阅cl-stream。