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

标签 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

我怎样才能创建一个行为如我所期望的二进制流,允许我写入一个值然后读回相同的值?我想要这样一个流来测试以流作为输入和输出到流的编码和解码函数的正确性。

最佳答案

双向流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 本地绑定(bind)到写入隐藏的内存序列的流,并最终返回该序列。整个表达式返回字节缓冲区:

#(205 204 204 204 204 220 94 64)

此缓冲区被提供给 with-input-from-sequence 以将 in 绑定(bind)到从该序列读取数据的本地流。 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-streams 破解一些东西(但这很危险,在某些情况下数据一致性会中断),或者从灰色流构建一个;另见 cl-stream .

关于lisp - 如何在 Common Lisp 中创建双向二进制流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56853321/

相关文章:

clojure - Lisp解释时 "reader"的任务是什么?

lisp - 用于回文的小型 lisp 程序的困难

lisp - 一个简单的 lisp 函数

performance - 为什么这种简化会使我的函数变慢?

common-lisp - 在 Common Lisp 中取消定义一个类及其所有方法

math - 方案函数对偶数求和

macros - 宏扩展到相同的运算符

lisp - lisp 中的 '((1 2)(3 4)) and ' ('(1 2 )' (3 4)) 有什么区别?

binding - Lisp 中的哪个函数允许您比较变量名而不是它所包含的内容?

macros - 调用函数的宏在解释器中有效,在编译器中失败(SBCL + CMUCL)