Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read binary file containing 32 Bit floating points in JavaScript

Currently, when the binary file contains 64 Bit floating points, I do:

fs.open('doubles.bin', 'r', (err, fd) => {
  if (err) reject(err);
  const buf = new Buffer(size);
  fs.read(fd, buf, 0, size, start, (err2) => {
    if (err2) reject(err2);
    const f32 = new Float32Array(buf.buffer);
    const data = Array.prototype.slice.call(f32);
    resolve({ id, data });
  });
});

(the binary is a simple list of numbers. They are not separated by anything)

I think this works because the Float32Array view expects to read the standard JavaScript Numbers, which are 64 Bit in size.

As soon as the binary contains 32 Bit Numbers, i only get garbage out of it (NaNs and wrong Numbers).

How can I read a binary file, containing 32 Bit floating point numbers, with JavaScript and convert it to an Array?

like image 347
v2blz Avatar asked Jun 27 '26 05:06

v2blz


1 Answers

Use the getFloat32 method of the DataView class. Depending on how your data is stored you also need the littleEndian flag.

There are slight incompatibilities between Node's Buffer and TypedArrays. The only safe way is to manually copy every byte over from the Buffer to a ArrayBuffer. Or in your case don't use TypedArrays at all and use the node methods.

This outputs the second and the third double (64 bit) in big endian (we skip 8 bytes and read the next 16 bytes from the file).

var fs = require('fs');

var position = 8;
var length = 16;

fs.open('./doubles.bin', 'r', function(err, fd) {
    if(err) {
        return console.error(err);
    }

    var buffer = new Buffer(length);

    fs.read(fd, buffer, 0, length, position, function(err, bytesRead) {
        if(err) {
            return console.error(err);
        }

        console.log(buffer.readDoubleBE(0));
        console.log(buffer.readDoubleBE(8));
    });
});

0.37290650606155396
0.4405119717121124
like image 77
Prinzhorn Avatar answered Jun 28 '26 18:06

Prinzhorn