如何正确读取 Clojure 中的 RandomAccessFile?

Posted

技术标签:

【中文标题】如何正确读取 Clojure 中的 RandomAccessFile?【英文标题】:How to correctly read from RandomAccessFile in Clojure? 【发布时间】:2011-08-09 19:57:21 【问题描述】:

我一直在尝试开发一个用于在 Clojure 中读取 MPQ 文件的小库,我决定使用 RandomAccessFile,因为 MPQ 是一种二进制格式。

但是,我在使用 RandomAccessFile#read() 方法时遇到了问题,因为我不确定我是否正确调用它

代码如下:

(ns parser
  (:import (java.io RandomAccessFile)))


(with-open [file (RandomAccessFile. "replay.SC2Replay" "r")]
  (let [x (byte-array 16)]
    (.read file [x 0 16])))

当我运行代码时,我得到了

Exception in thread "main" java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to [B (parser.clj:0)
    at clojure.lang.Compiler.eval(Compiler.java:5440)
    at clojure.lang.Compiler.load(Compiler.java:5857)
    at clojure.lang.Compiler.loadFile(Compiler.java:5820)
    at clojure.main$load_script.invoke(main.clj:221)
    at clojure.main$script_opt.invoke(main.clj:273)
    at clojure.main$main.doInvoke(main.clj:354)
    at clojure.lang.RestFn.invoke(RestFn.java:409)
    at clojure.lang.Var.invoke(Var.java:365)
    at clojure.lang.AFn.applyToHelper(AFn.java:163)
    at clojure.lang.Var.applyTo(Var.java:482)
    at clojure.main.main(main.java:37)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to [B
    at parser$eval7.invoke(parser.clj:7)
    at clojure.lang.Compiler.eval(Compiler.java:5424)
    ... 15 more

异常。我也尝试为临时变量这样做

(let [x []]

但它都产生相同的异常。 Java中的相同代码将是这样的

RandomAccessFile file = new RandomAccessFile("replay.SC2Replay", "r");
byte[] x;
file.read(x, 0, 16);

【问题讨论】:

【参考方案1】:

您传入单个向量作为参数,它试图将其转换为字节数组,以便它可以调用接收字节数组的单个参数读取方法。只需按原样传递参数即可。

(with-open [file (RandomAccessFile. "replay.SC2Replay" "r")]
  (let [x (byte-array 16)]
    (.read file x 0 16)))

【讨论】:

以上是关于如何正确读取 Clojure 中的 RandomAccessFile?的主要内容,如果未能解决你的问题,请参考以下文章

如何在clojure中读取stdin(* in *)中的行

在 Clojure 1.3 中,如何读写文件

Clojure 懒惰地从文件中读取随机行

在 Clojure 中,如何配置 Korma 和 Ragtime 以使用相同的数据库?

如何在 Clojure 中将 XML 转换为 edn?

如何使承诺因clojure中的错误而失败?