【问题标题】:how to decode bson by java or clojure如何通过java或clojure解码bson
【发布时间】:2015-02-11 02:23:58
【问题描述】:

我想将 BSON 文件解码为 Clojure 映射。

这是我的代码:

(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]
  (->> (.readObject decoder b) (.toMap) (into {})))

(defn read-bson
  [path]
 (clojure.walk/keywordize-keys (bson2map (read-file path))))

但是当我解码像 (r/read-bson "test.bson") 这样的 BSON 文件时,它只解码第一条记录,我想解码所有记录。 test.bson 太大了。如何分片解码?


然后我找到了一个名为LazyBSONDecoder的类,写了一些java代码,它可以工作,它可以解码所有记录。

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);
    }
}

所以我更改了 Clojure 代码,将 BasicBSONDecoder 替换为 LazyBSONDecoder,但它总是只解码第一条记录。

(defonce decoder (LazyBSONDecoder.))

(defn bson2map [^Byte b]
  (do (print (.readObject decoder b))
      (print (.readObject decoder b))
      (print (.readObject decoder b))))

【问题讨论】:

  • Java 版本有一个do/while 循环,而您的Clojure 版本只调用一次readObject 方法。
  • @myguidingstar 在最后一个示例中,有三个对 .readObject 的调用,但根据 OP,所有这些调用都会返回第一条记录。
  • @ipaomian 能否提供一个示例 BSON 文件来检查问题所在?
  • @tolitius @juan.facoorro 谢谢你给我一些建议,我已经解决了问题,函数bson2map参数应该是一个inputStream但没有字节数组。LazyBSONDecoder

标签: java clojure bson


【解决方案1】:

请看这段代码LazyBSONDecoder

函数bson2map参数应该是inputStream而不是字节数组,如果是字节数组,它将返回一个新的ByteArrayInputStream,所以我总是得到第一条记录。

【讨论】:

    猜你喜欢
    • 2016-12-08
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多