在node.js上保存float32array到磁盘的紧凑方法是什么?
JSON.stringify显然不是空间有效的。 使用Node.js序列化和存储float32array的最优雅的方法是什么?
编辑:由于“基于意见”和“缺乏对问题的理解”等原因,人们正在closures这个问题。 我认真相信第一个是一个missclick。 对于第二个,也许这更清楚:
var fs = require("fs"); var len = 1000*1000*10; var big_array = new Float32Array(len); for (var i=0; i<len; ++i) big_array[i] = Math.random(); // OBVIOUSLY NOT SPACE EFFICIENT \/ fs.writeFileSync("big_array.json",JSON.stringify(big_array));
这不是空间有效的,因为你将数字表示为string,所以8字节的浮点数将使用多达20个utf8字符,这是浪费。 问题是:如何以节省空间的方式存储数组?
最后,我设法将float32array写入到具有nodejs的磁盘上,并在浏览器中检索它们,我希望它能帮助你。
在NodeJS中将Float32Array写入二进制文件
var fs = require('fs'); var wstream = fs.createWriteStream('data.dat'); var data = new Float32Array([1.1,2.2,3.3,4.4,5.5]); //prepare the length of the buffer to 4 bytes per float var buffer = new Buffer(data.length*4); for(var i = 0; i < data.length; i++){ //write the float in Little-Endian and move the offset buffer.writeFloatLE(data[i], i*4); } wstream.write(buffer); wstream.end();
读取文件并将其转换为浏览器上的Float32Array
var urlToFloatFile = 'data.dat'; var request = new XMLHttpRequest(); request.open('GET', urlToFloatFile, true); //specify the response type as arraybuffer request.responseType = 'arraybuffer'; request.onload = function (msg) { var yourFloatData = new Float32Array(this.response); console.log(yourFloatData); }; request.send();
感谢来自WebGL Dev List GGroup https://groups.google.com/forum/#!topic/webgl-dev-list/EbGUi_iSEx8的@ben_a_adams的客户端代码
我创build了一个简单的testing来testing浮点数组的JSON序列化与二进制表示的不同之处,结果如下:
-
2.000.000浮点值
-
7.8MB的二进制文件
-
JSON文件上38.5MB
-
17.5在一个Gzipped的JSON文件
实际上有一个更简单的版本可能
let fs = require('fs') let data = [150, 180] fs.writeFileSync('mydata', new Buffer(new Uint32Array(data).buffer)) fs.readFile('mydata', (err, buf) => { let restoredData = new Uint32Array(buf.buffer, buf.offset, buf.byteLength/4) console.log(data[1]) console.log(restoredData[1]) });
我相信你可以使用meteor的EJSON:
https://npmjs.org/package/meteor-ejson
EJSON是JSON的扩展,支持更多的types。 它支持所有JSON安全types,以及:
- date(JavaScriptdate)
- 二进制(JavaScript Uint8Array或EJSON.newBinary的结果)
- 用户定义的types(请参阅EJSON.addType。例如,Meteor.Collection.ObjectID以此方式实现。)