4

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?

Jake Wilson
  • 88,616
  • 93
  • 252
  • 370
  • 1
    The result of `fs.readFileSync('/some/path/to/image.jpg')` is not a filepath even if it is a buffer. Unless the contents of that file is a filepath. You should pass `'/some/path/to/image.jpg'` to `fs.statSync` – Dan D. Apr 20 '18 at 20:57
  • 1
    You may provide a filepath as either String, Buffer, or URL to `fs.statSync`. But a 6MB JPEG is not a filepath. – Dan D. Apr 20 '18 at 20:59

2 Answers2

12

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.

zero298
  • 25,467
  • 10
  • 75
  • 100
  • 1
    Ah okay that is making more sense now. Totally didn't consider that once a file is read into memory the filesystem wouldn't know any details about it. Thanks – Jake Wilson Apr 20 '18 at 21:16
1

It does not say Buffer must be whole file content.

From documentation You can see that first argument is path.

You could be correct if You they wrote in manual that argument must be body, content or something alike.

So such code will work.

const imageFile = '/some/path/to/image.jpg';
let imageStats, imageBuffer;

try {
  imageStats = fs.statSync(imageFile);
  imageBuffer = fs.readFileSync(imageFile);
} catch (e) {
  console.log('error reading in file', e)
}

But I'm sure we should require community to add examples in documentations.

Otherwise it's ambiguous.

num8er
  • 18,604
  • 3
  • 43
  • 57