Nodejs:如何使用node.js读取二进制存储的浮点型数据文件,将其转换为对应的浮点数组?
Nodejs:如何使用node.js读取二进制存储的浮点型数据文件,将其转换为对应的浮点数组?
var rs = fs.createReadStream(‘data/soucd1.id.2014060113.grd’, { highWaterMark: 4,start: 0, end: 1821724 } ); rs.on(“data”, function (chunk){ console.log(chunk.readFloatBE(0,true)); });
我尝试用上面这种方式去做,可是读出来的数据好像不对,我对createReadStream函数不是很明白,求解答!
Node.js:如何使用Node.js读取二进制存储的浮点型数据文件,并将其转换为对应的浮点数组?
问题描述
用户试图使用 fs.createReadStream
方法来读取一个二进制文件中的浮点数数据,并将其转换为浮点数组。然而,当前的实现并没有达到预期的效果。
解决方案
要正确地读取二进制文件中的浮点数并将其转换为浮点数组,我们需要理解几个关键概念:
- 文件流:通过
fs.createReadStream
创建的可读流允许我们逐块读取文件内容。 - 二进制读取:使用
Buffer
对象的方法来解析二进制数据。 - 浮点数格式:浮点数在二进制中以特定格式存储,需要使用正确的方法来读取。
以下是正确的实现步骤:
- 创建可读流:使用
fs.createReadStream
方法创建一个可读流。 - 监听
data
事件:当有新的数据块可用时,处理这些数据块。 - 解析浮点数:使用
Buffer
的方法(如readFloatBE
)将二进制数据转换为浮点数。
示例代码
const fs = require('fs');
// 创建一个可读流
const rs = fs.createReadStream('data/soucd1.id.2014060113.grd', {
highWaterMark: 4,
start: 0,
end: 182 * 172 * 4 // 计算文件大小(假设每个浮点数占用4个字节)
});
let floatArray = [];
// 监听 'data' 事件
rs.on("data", function (chunk) {
for (let i = 0; i < chunk.length; i += 4) {
const float = chunk.readFloatBE(i);
floatArray.push(float);
}
});
// 监听 'end' 事件
rs.on("end", function () {
console.log(floatArray); // 输出浮点数组
});
代码解释
- 创建可读流:
fs.createReadStream
方法用于创建一个可读流,参数包括文件路径、高水位标记(highWaterMark
)、起始位置和结束位置。 - 监听
data
事件:每当有新的数据块可用时,data
事件被触发。在这个事件处理程序中,我们遍历每个数据块,并使用readFloatBE
方法从二进制数据中提取浮点数。 - 监听
end
事件:当文件读取完毕时,end
事件被触发。此时,所有的浮点数已经被成功读取并存储到floatArray
中。
通过这种方法,我们可以正确地读取二进制文件中的浮点数,并将其转换为浮点数组。
readStream和writeStream一般来 说比较底层,其实也可以用比较高层的读文件方法
var fs = require(‘fs’); var buff = new Buffer(8); buff.writeUInt32BE(1111, 0); buff.writeFloatBE(3.14,4); fs.writeFile(‘data.bin’, buff,{encoding:‘hex’}, function (err) { if (err) throw err; console.log(‘写入成功’); })
fs.readFile(‘data.bin’, { encodinig: ‘hex’ }, function (err, data) { if (err) throw err; console.log(data.readUInt32BE(0)); console.log(data.readFloatBE(4)); });
上面的方法就可以,read相关的方法有一个offset的参数 ,就是用来指定从哪个位置开始读取。单精点浮点总是32位,所以你找到开始位置,循环读就可以了。
要使用Node.js读取二进制存储的浮点型数据文件并将其转换为对应的浮点数组,你可以使用fs
模块来读取文件,并使用readFloatBE
或readFloatLE
方法来解析每个浮点数。以下是一个完整的示例代码,展示了如何实现这一过程:
const fs = require('fs');
// 创建一个可读流
const rs = fs.createReadStream('data/source1.id.2014060113.grd', { highWaterMark: 4, start: 0, end: 182 * 172 * 4 });
// 用于存储解析后的浮点数数组
let floatArray = [];
// 当有数据时触发
rs.on("data", function (chunk) {
for (let i = 0; i < chunk.length; i += 4) {
// 每次读取4个字节(即一个浮点数)
let float = chunk.readFloatBE(i);
floatArray.push(float);
}
});
// 文件读取完成时触发
rs.on("end", function () {
console.log(floatArray);
});
解释
fs.createReadStream
:创建一个从指定文件读取数据的可读流。highWaterMark
: 设置内部缓存大小(单位是字节),这里设置为4,表示每次读取4个字节的数据。start
和end
: 指定读取的起始位置和结束位置。在这个例子中,假设文件大小为1821724字节。chunk.readFloatBE(i)
: 从当前chunk
中以大端序读取浮点数。
通过这种方式,你可以将整个文件中的所有浮点数读取到一个数组中,然后根据需要进行处理。注意这里的示例假设每个浮点数占用4个字节,并且是大端序存储。如果文件是以小端序存储,则应使用chunk.readFloatLE(i)
。