Writing and reading typedArray in nodejs the right way

Issue

I am trying to write an Uint16Array to a file and later retrieve it with NodeJS, I am successful but it feels like I’m doing it the wrong way.

"use strict";

const fs = require("fs").promises;

const A = new ArrayBuffer(20);
const a = new Uint16Array(A);

for(let i=0;i<a.length;++i){
    a[i]=i;
}

(async()=>{
    await fs.writeFile("test.txt",a,"binary")
    .catch((err)=>{console.error(err)});

    const buf = await fs.readFile("test.txt")
    .catch((err)=>{console.error(err)});

    const b = new Uint16Array((new Uint8Array(buf)).buffer);
    //^ feels wonky, like instead of just using the buf I have to
    //make a temporary Uint8Array of buf and then take its buffer
    //
    //if I don't do it this way b will be [0,1,0,2,0,3,0 ... etc]

    console.log("A=",A,"\na=",a);
    console.log("buffer=",buf,"\nb=",b);
})()

The code above works and gives me the following result:

enter image description here

It doesn’t look right, notice how I’m setting the b variable to an Uint16Array which is set by a dummy array of Uint8Array of the buffer. I don’t want to have the dummy Uint8Array in there.

In production the files will be much larger, on the order of megabytes, I rather do things correct now than later.

Solution

"This happens because the Buffer class is a subclass of JavaScript’s Uint8Array class and not a Uint16Array array"

Refer to the following stackoverflow… Read/Write a typed array to file with node.js

To correct:

 //const b =  new Uint16Array((new Uint8Array(buf)).buffer);
 //Change to this...
 const d = new Uint16Array(buf.buffer,buf.byteOffset,buf.length/2);

To show the difference’s I added this to your code.

const b =  new Uint16Array((new Uint8Array(buf)).buffer);
const c = new Uint16Array(buf);
const d = new Uint16Array(buf.buffer,buf.byteOffset,buf.length/2);

//^ feels wonky, like instead of just using the buf I have to
//make a temporary Uint8Array of buf and then take its buffer
//
//if I don't do it this way b will be [0,1,0,2,0,3,0 ... etc]

console.log("A=",A,"\na=",a);
console.log("buffer=",buf,"\nb=",b);
console.log("buffer=",buf,"\nc=",c);
console.log("buffer=",buf,"\nd=",d);

Here are the results….

Terminal Output

Answered By – hancockm

Answer Checked By – Cary Denson (AngularFixing Admin)

Leave a Reply

Your email address will not be published.