You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Clojure中实时读取Linux下/dev/input/js0的游戏控制器数据?

解决Clojure实时读取游戏控制器事件的问题

你的代码出现批量输出的核心原因是输出流缓冲:Clojure的print默认使用缓冲机制,不会立即将内容刷到控制台,只有当缓冲区满或者遇到换行时才会输出。另外,直接逐个读取字节也不符合游戏手柄事件的结构(/dev/input/js0的每个事件是固定8字节的二进制数据)。

修复方案

以下代码会解决缓冲问题,同时正确读取完整的手柄事件并实时输出:

(with-open [is (clojure.java.io/input-stream "/dev/input/js0")]
  (let [buffer (byte-array 8)] ; 每个js事件固定8字节
    (loop []
      (.read is buffer) ; 一次性读取完整事件
      (println (vec buffer)) ; 将字节数组转为向量方便查看
      (.flush *out*) ; 强制刷新输出流,确保实时显示
      (recur))))

关键改进点

  • 使用8字节数组一次性读取完整的游戏手柄事件,符合/dev/input/js0的设备数据格式(每个事件包含时间戳、事件类型、按键/轴编号、数值)。
  • 每次输出后调用.flush *out*,强制清空输出缓冲区,让内容立即显示在控制台。
  • 用println替代print,既添加换行让输出更易读,也能辅助触发缓冲刷新(不过核心还是手动调用.flush)。

贴近cat命令的原始输出版本

如果需要完全模仿cat /dev/input/js0的原始字节输出效果,可以直接将字节写入标准输出流,避免字符串转换的缓冲:

(with-open [is (clojure.java.io/input-stream "/dev/input/js0")
            os (clojure.java.io/output-stream System/out)]
  (let [buffer (byte-array 1024)]
    (loop []
      (let [read-bytes (.read is buffer)]
        (when (> read-bytes 0)
          (.write os buffer 0 read-bytes)
          (.flush os)
          (recur))))))

这个版本直接将读取到的字节写入标准输出,实时性和输出效果和cat /dev/input/js0完全一致。

内容的提问来源于stack exchange,提问作者epalma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 00:05:25