title: how to decode bson by java or clojure
body: <p>I want to decode a BSON file to a Clojure map. </p>
  
  <p>This is my code: </p>
  
  <pre><code>(ns decode
    (:require [clojure.java.io :as cji])
    (:import [org.bson BasicBSONObject BasicBSONEncoder BasicBSONDecoder]))
  
  (defonce encoder (BasicBSONEncoder.))
  
  (defonce decoder (BasicBSONDecoder.))
  
  (defn read-file [file-path]
    (with-open [reader (cji/input-stream file-path)]
      (let [length (.length (clojure.java.io/file file-path))
            buffer (byte-array length)]
        (.read reader buffer 0 length)
        buffer)))
  
  
  (defn bson2map [^Byte b]
    (-&gt;&gt; (.readObject decoder b) (.toMap) (into {})))
  
  (defn read-bson
    [path]
   (clojure.walk/keywordize-keys (bson2map (read-file path))))
  </code></pre>
  
  <p>But when I decode a BSON file like this <code>(r/read-bson "test.bson")</code>, it just decodes the first record and I want to decode all of them. The <code>test.bson</code> is too big. How do I decode it in fragments?</p>
  
  <hr>
  
  <p>Then I found a class called <code>LazyBSONDecoder</code>, wrote some java code and it works, it can decode all of the records.</p>
  
  <pre><code>import org.bson.LazyBSONDecoder;
  
  import java.io.FileInputStream;
  import java.io.IOException;
  import java.io.InputStream;
  
  public class Main {
  
      public static void main(String[] args) throws IOException {
          InputStream in = new FileInputStream("./_Installation.bson");
          LazyBSONDecoder decoder = new LazyBSONDecoder();
          Object obj;
          int count = 0;
          try {
              do {
                  obj = decoder.readObject(in);
                  System.out.println(obj);
                  count++;
              } while (obj != null);
          } catch (Exception e) {
              // ignore
          }
          System.out.println(count);
      }
  }
  </code></pre>
  
  <hr>
  
  <p>So I changed the Clojure code replacing the <code>BasicBSONDecoder</code> for the <code>LazyBSONDecoder</code> but it always just decodes the first record.</p>
  
  <pre><code>(defonce decoder (LazyBSONDecoder.))
  
  (defn bson2map [^Byte b]
    (do (print (.readObject decoder b))
        (print (.readObject decoder b))
        (print (.readObject decoder b))))
  </code></pre>