读取bson文件——JavaScript读取/解析bson文件并存至txt文件

由于最近项目需要,不得不读取 .bson 文件,网上都是读取 json 的,关于 bson 的几乎没有!!折腾了两天,最终整理出个路子,如下:

首先是通过 JavaScript 读取的,为啥要用这个语言,不知道不清楚不了解!!!好吧,实际上是 libbson(C++)没搞出来,一没文档,二没帖子,看源码也没看出个所以然;Python 就更别说了(┭┮﹏┭┮被逼地简直头皮发麻***)

要说明的是,我是需要读取 .bson 文件中的特定内容,也就是指定元素的值。 libbson 提供了掰着手指头都能数得过来的几个例子,有一个是可以读取bson文件然后输出到命令行的,是一股脑地输出,不想要的也输出,而且没有层次,长下面这鬼样纸:

所以最终还是用 JS 实现的。

JS无需编译,直接运行 .js 文件即可。这里是通过 Node.js (一个方便使用 JavaScript 的环境)实现的,使用方法如下:

node bson_gao.js gao.bson 789.txt

node 就是用 Node.js 启动,bson_gao.js 是我编写的读取 bson 文件的脚本,gao.bson 是要读取的文件,123.txt 是最终要存储数据的文件。

运行这个指令后会出现一堆莫名其妙的文件,本人不是专业搞 JS 的,所以也不清楚运作机理,不过这些都不重要。重要的是,程序会读取 gao.bson 文件,然后把需要读取的数据存入 123.txt。

运行代码前,当然要先装上 Node.js,并且在里面下载好 fs 和 bson 模块,这个网上搜一下有很多资料的。

bson_gao.js 代码如下:

 1 const fs = require("fs");
 2 const bson = require('bson');
 3 
 4 var fileName = process.argv.splice(2);    //读取命令行输入参数,从第3个开始
 5 console.log("读取内容为 : ");
 6 fs.readFile(fileName[0].toString(),
 7     function(err,data){
 8        if(err){
 9            console.error(err);
10        }
11        else{
12            var mappoints = bson.deserialize(data);
13            let mapPointsCount = 0;
14 
15            for(let pointIndex in mappoints){
16                let pos = getPosition(mappoints[pointIndex]['mWorldPos']);
17                let pos_x = pos.x;
18                let pos_y = pos.y;
19                let pos_z = pos.z;
20                console.log(pos_x + '	' + pos_y + '	' + pos_z);
21                mapPointsCount ++;
22                writeToTxt('pos_x:'+pos_x + '	' + 'pos_y:'+pos_y + '	' + 'pos_z:'+pos_z + '
');
23            }
24            console.log("Number of data : " + mapPointsCount);
25        }
26     }
27 );
28 
29 //定义的子函数
30 
31 function getPosition (worldPos){
32   var buf = worldPos['data']['buffer'];
33   return {
34     'x': buf.readFloatLE(0),
35     'y': buf.readFloatLE(4),
36     'z': buf.readFloatLE(8)
37   }
38 }
39 
40 function writeToTxt(_data){
41   fs.writeFile(fileName[1].toString(),_data,{flag:'a'},function(err){
42      if(err)
43          console.log("文件写入失败")
44   });
45 }

我的这个bson文件保存的是关于点云的数据,当然还有一些乱七八糟的,我要读取的是 mWorldPos,保存了 x、y、z 三个坐标值,每个值占 4 个字节(32位)。所以我首先要确定每个 mWorldPos 的位置,然后从它的 buffer 里分别读取三个坐标数据。

我的 gao.bson 的部分数据(通过 libbson 读取的):

{ "0" : { "mnId" : "30", "nNextId" : "156441", "mnFirstKFid" : { "$numberLong" : "2"}, "mnFirstFrame" : { "$numberLong" : "64"}, "nObs" : { "$numberInt" : "5" }, "mTrackProjX" : { "$numberDouble" : "511.873443603515625" }, "mTrackProjY" : { "$numberDouble" : "37.295444488525390625" }, "mTrackProjXR" : { "$numberDouble" : "511.873443603515625" }, "mbTrackInView" : false, "mnTrackScaleLevel" : { "$numberInt" : "0" }, "mTrackViewCos" : { "$numberDouble" : "0.99079859256744384766" }, "mnTrackReferenceForFrame" : "5215", "mnLastFrameSeen" : "106", "mnBALocalForKF" : "611", "mnFuseCandidateForKF" : "313", "mnLoopPointForKF" : "608", "mnCorrectedByKF" : "0", "mnCorrectedReference" : "0", "mPosGBA" : { "rows" : { "$numberLong" : "3"}, "cols" : { "$numberLong" : "1"}, "type" : { "$numberLong" : "5"}, "data" : { "$binary" : { "base64": "RZ4+Pzs14L9m31RA", "subType" : "00" } } }, "mnBAGlobalForKF" : "621", "mWorldPos" : { "rows" : { "$numberLong" : "3"}, "cols" : { "$numberLong" : "1"}, "type" : { "$numberLong" : "5"}, "data" : { "$binary" : { "base64": "RZ4+Pzs14L9m31RA", "subType" : "00" } } }, "mObservations" : [ [ "7", "22" ], [ "1", "105" ], [ "3", "385" ], [ "2", "121" ], [ "6", "274" ] ], "mNormalVector" : { "rows" : { "$numberLong" : "3"}, "cols" : { "$numberLong" : "1"}, "type" : { "$numberLong" : "5"}, "data" : { "$binary" : { "base64": "J7BnPnsp576v6Vw/", "subType" : "00" } } }, "mDescriptor" : { "rows" : { "$numberLong" : "1"}, "cols" : { "$numberLong" : "32"}, "type" : { "$numberLong" : "0"}, "data" : { "$binary" : { "base64": "ghQf++KkvVe8W1N2tP4saec7P4GznRNT1ar6iJhAobs=", "subType" : "00" } } }, "mpRefKF" : "2", "mnVisible" : { "$numberInt" : "151" }, "mnFound" : { "$numberInt" : "19" }, "mbBad" : false, "mfMinDistance" : { "$numberDouble" : "1.1126192808151245117" }, "mfMaxDistance" : { "$numberDouble" : "3.9867167472839355469" } }, "1" : { "mnId" : "31", "nNextId" : "156441", "mnFirstKFid" : { "$numberLong" : "2"}, "mnFirstFrame" : { "$numberLong" : "64"}, "nObs" : { "$numberInt" : "9" }, "mTrackProjX" : { "$numberDouble" : "513.37762451171875" }, "mTrackProjY" : { "$numberDouble" : "39.406429290771484375" }, "mTrackProjXR" : { "$numberDouble" : "513.37762451171875" }, "mbTrackInView" : false, "mnTrackScaleLevel" : { "$numberInt" : "0" }, "mTrackViewCos" : { "$numberDouble" : "0.99058109521865844727" }, "mnTrackReferenceForFrame" : "5215", "mnLastFrameSeen" : "112", "mnBALocalForKF" : "611", "mnFuseCandidateForKF" : "313", "mnLoopPointForKF" : "608", "mnCorrectedByKF" : "0", "mnCorrectedReference" : "0", "mPosGBA" : { "rows" : { "$numberLong" : "3"}, "cols" : { "$numberLong" : "1"}, "type" : { "$numberLong" : "5"}, "data" : { "$binary" : { "base64": "QndHP4Ia5r/8pl9A", "subType" : "00" } } }, "mnBAGlobalForKF" : "621", "mWorldPos" : { "rows" : { "$numberLong" : "3"}, "cols" : { "$numberLong" : "1"}, "type" : { "$numberLong" : "5"}, "data" : { "$binary" : { "base64": "QndHP4Ia5r/8pl9A", "subType" : "00" } } }, "mObservations" : [ [ "7", "18" ], [ "1", "109" ], [ "3", "25" ], [ "2", "122" ], [ "6", "275" ], [ "4", "30" ], [ "9", "18" ], [ "8", "20" ], [ "10", "20" ] ], "mNormalVector" : { "rows" : { "$numberLong" : "3"}, "cols" : { "$numberLong" : "1"}, "type" : { "$numberLong" : "5"}, "data" : { "$binary" : { "base64": "mC1fPi3U6r6sbFw/", "subType" : "00" } } }, "mDescriptor" : { "rows" : { "$numberLong" : "1"}, "cols" : { "$numberLong" : "32"}, "type" : { "$numberLong" : "0"}, "data" : { "$binary" : { "base64": "UpC/+OrkPderW9BztP9se+fzP5GTS7Lh2bJ+ypxQpXs=", "subType" : "00" } } }, "mpRefKF" : "2", "mnVisible" : { "$numberInt" : "176" }, "mnFound" : { "$numberInt" : "47" }, "mbBad" : false, "mfMinDistance" : { "$numberDouble" : "1.1623446941375732422" }, "mfMaxDistance" : { "$numberDouble" : "4.1648921966552734375" } }, "2" : { "mnId" : "3", "nNextId" : "156441", "mnFirstKFid" : { "$numberLong" : "2"}, "mnFirstFrame" : { "$numberLong" : "64"}, "nObs" : { "$numberInt" : "3" }, "mTrackProjX" : { "$numberDouble" : "-0.34699571132659912109" }, "mTrackProjY" : { "$numberDouble" : "-102.95076751708984375" }, "mTrackProjXR" : { "$numberDouble" : "-0.34699571132659912109" }, "mbTrackInView" : false, "mnTrackScaleLevel" : { "$numberInt" : "1" }, "mTrackViewCos" : { "$numberDouble" : "0.77780538797378540039" }, "mnTrackReferenceForFrame" : "5215", "mnLastFrameSeen" : "176", "mnBALocalForKF" : "611", "mnFuseCandidateForKF" : "89", "mnLoopPointForKF" : "608", "mnCorrectedByKF" : "0", "mnCorrectedReference" : "0",

最后存储的 123.txt 部分数据(通过 bson_gao.js 存储):

pos_x:11.609704971313477 pos_y:-9.638463020324707 pos_z:48.26372146606445
pos_x:16.311811447143555 pos_y:-0.7860449552536011 pos_z:42.86808776855469
pos_x:-12.45207405090332 pos_y:-7.568289279937744 pos_z:47.80936050415039
pos_x:15.905488967895508 pos_y:-7.598543643951416 pos_z:45.10790252685547
pos_x:16.373966217041016 pos_y:-1.6582328081130981 pos_z:42.468746185302734
pos_x:6.332942962646484 pos_y:-8.755221366882324 pos_z:39.46611022949219
pos_x:16.789087295532227 pos_y:-0.8732663989067078 pos_z:46.31952667236328
pos_x:5.774340629577637 pos_y:-9.464967727661133 pos_z:41.57020950317383
pos_x:0.9664075374603271 pos_y:-2.1578664779663086 pos_z:35.57773971557617
pos_x:3.38576602935791 pos_y:-10.23925495147705 pos_z:43.15412139892578
pos_x:16.545536041259766 pos_y:-1.392843246459961 pos_z:46.86875915527344
pos_x:17.851194381713867 pos_y:-8.643896102905273 pos_z:58.38813781738281
pos_x:18.102949142456055 pos_y:-5.744359493255615 pos_z:53.23180389404297
pos_x:18.095937728881836 pos_y:-0.978411078453064 pos_z:41.19490432739258
pos_x:-5.2878923416137695 pos_y:-3.3611886501312256 pos_z:57.568790435791016
pos_x:-4.955174922943115 pos_y:-18.943540573120117 pos_z:78.9381103515625
pos_x:14.425850868225098 pos_y:-9.960193634033203 pos_z:45.55425262451172
pos_x:3.803712844848633 pos_y:-1.2650833129882812 pos_z:42.81630325317383
pos_x:8.404397010803223 pos_y:-4.206243515014648 pos_z:38.56267547607422
pos_x:10.646106719970703 pos_y:-2.663133144378662 pos_z:33.2987174987793
pos_x:18.19788360595703 pos_y:-4.282032012939453 pos_z:37.866153717041016
pos_x:3.149993896484375 pos_y:-14.502290725708008 pos_z:66.28900146484375
pos_x:18.281272888183594 pos_y:-3.59720516204834 pos_z:37.58603286743164
pos_x:16.164188385009766 pos_y:-5.562918663024902 pos_z:43.636688232421875
pos_x:10.910879135131836 pos_y:-10.468049049377441 pos_z:49.67988204956055
pos_x:9.463968276977539 pos_y:-4.861118793487549 pos_z:37.85740661621094
pos_x:5.207038879394531 pos_y:-10.244396209716797 pos_z:40.54631805419922
pos_x:9.275063514709473 pos_y:-8.239974975585938 pos_z:37.77473068237305
pos_x:15.380149841308594 pos_y:-5.8706159591674805 pos_z:44.781829833984375
pos_x:5.903839588165283 pos_y:-9.801711082458496 pos_z:39.871360778808594

可以看到变得很工整,而且都是有用的数据。事实上,你懂得,存储的时候可以按照自己想要存储的格式保存到 txt,比如我这个可以去掉 pos_x、pos_y、pos_z 这些字母,每行只保留三个数字。

好吧,就这样吧,放松一下 b( ̄▽ ̄)d ~~~ kebawoleihuaile!!!!

原文地址:https://www.cnblogs.com/hxzkh/p/10045864.html