一、前言
MongoDB也是項目的備選平台,需要用Java和C/C++進行操作。別的不多說,幾個關鍵要求:
1 Collection的列有int, long和BinData(也即二進制數組)類型;
2 Java和C程序寫入的數據可以互相讀取。
二、Java實現BinData讀
Java工程里引入mongo-java-driver.jar依賴即可,示例代碼很多,這里就不貼了。
別的Column都簡單,僅僅在讀取BinData時有些麻煩,因為MongoDB的Java API沒有直接提供getBinary之類的接口。
解決辦法是:引入org.bson.types.Binary類,再轉換一下即可:
Binary binary = (Binary) doc.get("Data"); obj.setData((byte[]) binary.getData());
順便說一下,寫BinData直接用doc.append()即可,無須擔心。
另外,C/C++ API使用的是mongo-c-driver,其中對BinData都有專門的接口,也比較簡單。
三 、C/C++程序的讀取順序
測試過程中曾出現一個奇怪的問題,就是C/C++程序寫入的數據,Java程序可以正取讀取,反之則不行。
折騰半天后找到原因:Java API中讀取用的是doc.getXxxx(String )方法,與順序無關。
MongoCursor<Document> cursor = collection.find(docFilter).iterator(); while (cursor.hasNext()) { Document doc = cursor.next(); //讀取順序無所謂 int col2 = doc.getInteger("COL2").intValue(); long col3 = doc.getLong("COL3").longValue(); int col1 = doc.getInteger("COL1").intValue(); ... }
而在C/C++ API中,讀取用的是bson_iter_find(bson_iter_t*, const char*)和bson_iter_xxxx(bson_iter_t*)函數的組合,這里順序很重要,必須與寫入時保持一致(寫入順序和存儲順序也是一致的)。
mongoc_cursor_t cursor = mongoc_collection_find_with_opts(collection, query, NULL, NULL);
while (mongoc_cursor_next(cursor, &doc))
{
int col1, col2;
long col3;
bson_iter_t iter;
bson_iter_init (&iter, doc);
//必須與寫入時順序一致
if (bson_iter_find(&iter, "COL1"))
col1 = bson_iter_int32(&iter);
if (bson_iter_find(&iter, "COL3"))
col3 = bson_iter_int64(&iter);
if (bson_iter_find(&iter, "COL2"))
col2 = bson_iter_int32(&iter);
...
}
假設寫入數據的順序是COL1, COL2, COL3,則上段代碼中只能獲得col1和col2的值,而col3將被跳過。
項目中,將Java程序和C/C++程序的寫入順序都調整一致,再在C/C++程序中按相同順序讀取,問題解決。