1

我是 Clojure 的新手,我需要 Clojure 为我做一个简单的任务,相当于下面的 Java 代码:

MappedByteBuffer out = new RandomAccessFile("file", "rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 100);

但是 Clojure 是一种动态语言,map() 返回 DirectByteBuffer 而不是 MappedByteBuffer。我希望使用 setInt() 方法,它是 MappedByteBuffer 的成员。有没有办法告诉 Clojure 使用 MappedByteBuffer 中的方法而不是 DirectByteBuffer?

谢谢!

顺便说一句,这是我的尝试:

(defprotocol MfileP
  (at     [this pos])
  (get-i  [this])
  (set-i  [this val])
  (resize [this size])
  (fsize  [this]))

(defrecord Mfile [fc buf] MfileP
  (at     [this pos]  (.position buf pos))
  (get-i  [this]      (.getInt buf))
  (set-i  [this val]  (.setInt buf val))
  (resize [this size] (assoc this :buf (.map fc FileChannel$MapMode/READ_WRITE 0 size)))
  (fsize  [this]      (.size fc)))

(defn open [path]
  (let [fc (.getChannel (new RandomAccessFile path "rw"))]
    (let [buf (.map fc FileChannel$MapMode/READ_WRITE 0 (.size fc))]
      (Mfile. fc buf))))

表单 (set-i) 会引发异常,因为 Clojure 正在 DirectMapBuffer 中寻找 .setInt。

4

2 回答 2

4

你没有说你认为你已经建立了map()回归DirectByteBufferMappedByteBuffer不是——毫无疑问,它正在返回抽象类的子类。

MappedByteBuffer#setInt(int)根据 JDK 文档,没有方法。

您应该对接口进行编码。

看:

java.nio.FileChannel#map(...) javadocs

java.nio.MappedByteBuffer javadocs

于 2012-04-29T12:01:42.727 回答
0

有一个例子供你参考。

(require '[clojure.java.io :as io])
(import [java.io File RandomAccessFile])

(def ^:private map-modes
  {:private    java.nio.channels.FileChannel$MapMode/PRIVATE
   :read-only  java.nio.channels.FileChannel$MapMode/READ_ONLY
   :read-write java.nio.channels.FileChannel$MapMode/READ_WRITE})

(def ^:private map-perms
  {:private    "r"
   :read-only  "r"
   :read-write "rw"})

;; read a Memory-Mapped File
(with-open [file (RandomAccessFile. (File. "./data/test.txt") (map-perms :read-only))]
  (let [fc (.getChannel file)
        buffer (.map fc (map-modes :read-only) 0 (.size fc))]
    (println (.isLoaded buffer)) ;; false
    (println (.capacity buffer)) ;; size of file 7087200
    (doseq [i (range 0 (.limit buffer))]
      (print (char (.get buffer))))
    (println "End of reading a Memory-Mapped File")))
于 2021-05-24T23:51:07.327 回答