Search code examples
javascriptnode.jsfsstat

fs.statSync with Buffer "Error: Path must be a string without null bytes"


I have read in a file buffer like this:

let imageBuffer
try {
  imageBuffer = fs.readFileSync('/some/path/to/image.jpg')
} catch (e) {
  console.log('error reading in file', e)
}

Then I try to stat the buffer:

let imageStats = fs.statSync(imageBuffer)

I get the following error:

Error: Path must be a string without null bytes

But when I check the documentation it says that statSync accepts a Buffer:

path: string | Buffer | URL

And I double checked that the Buffer is in fact a Buffer:

console.log(imageBuffer instanceof Buffer) // returns true

Also checked the size:

console.log(imageBuffer.byteLength) // returns 5928109 which is the correct size

So what am I misunderstanding here? Can you only stat a file path? The error makes it sound this way. But the documentation seems to make it clear that you can provide a Buffer too.

Bug or am I misunderstanding something?


Solution

  • I think the documentation for fs.statSync(path) is ambiguous. I believe it is saying that it wants a path. The path can be <string> | <Buffer> | <URL>, but it needs to be a path.

    So don't give it the buffer of the whole file, you give it a buffer that, if turned back into a string, is the path to the file.

    In other words,

    • fs.statSync("C:/foo.txt");
    • fs.statSync(Buffer.from("C:/foo.txt"));
    • fs.statSync(new URL("/foo", "https://www.example.com");

    If you think about it, it makes sense too. How would an operating system be able to give you file system information about a a file's raw bytes? Once it's bytes, it loses the context of the file system. If you read in the contents of 2 identical files, their Buffers would be the same, yet the stat of either would give you different results. You want to stat a path, not contents.