1

I have a typed array and I want to write it to a binary file. I need it to be in big-endian byte order but I might not (usually won't be) on a big-endian machine. How do I get from my typed array to the binary file?

KCE
  • 1,159
  • 8
  • 25

1 Answers1

3

As you may know, the way to enforce endianness in javascript is with the DataView view. Once you've created a DataView view of your buffer, you can set and get the data from it in either big-endian or little-endian byte order.

Here's an example of turning a typed array (which may be in little- or big-endian byte order) into a Uint8Array (equivalent to Node's 'file' Buffer) in big-endian byte order. Notice that since the dataView is a just a view of the underlying buffer, the original array arr is now byte-swapped and we will write it to the file.

arr = new Float32Array([42]) // one value
dataView = new DataView(arr.buffer)
dataView.setFloat32(0, arr[0], false /* big-endian */)
buf = new Uint8Array(arr.buffer)

Now you can pass that Array into a node file-writing method since Uint8Array is compatible with Node's Buffer object. For example, if you already had opened a file and had the fd for it, then you could do something like this:

fs.writeSync(fd, buf)

For the sake of completeness, here's example code which handles the loop you would actually use with Float32-type data:

arr = new Float32Array([...]) // some initial data
...
dataView = new DataView(arr.buffer)
byteNum = 0;
for (let i = 0; i < arr.length; i++) {
  dataView.setFloat32(byteNum, arr[i]);
  byteNum += Float32Array.BYTES_PER_ELEMENT;
}

buf = new Uint8Array(arr.buffer)
fs.writeSync(fd, buf)

Note in the above that I didn't pass false to setFloat32 because that's the default.


(For more details on the writing part of this see: Writing files in Node.js)

KCE
  • 1,159
  • 8
  • 25
  • So where is the "specified endianness"? Is this "big-endian" or "little-endian", and how do you actually switch between the two? Because this is the title of your self answered question, yet I see nothing in the answer given which mentions any change of the byte-order. – Neil Lunn Apr 14 '18 at 10:14
  • The `set` and `get` methods on a `DataView` are specified in the last argument of the method. `false` means big-endian, and `true` means little-endian. See the docs on [setFloat32](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setFloat32) for example. – KCE Apr 14 '18 at 10:24