node.jsfilebuffertyped-arrays

Writing and reading typedArray in nodejs the right way


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