9

Reading fs.read and fs.write, it seems that in Node.js no interface to the C function lseek is directly exposed; the current file descriptor position can be changed right before any fs.read or fs.write by the argument position.

I strongly suspect that, at low level, the argument position is handled with an lseek call before the read or write operation, but what about the return value of lseek?

To be more specific, to get the current file descriptor position in C, I can write:

int position = lseek(fd, 0, SEEK_CUR);

Is there a way in Node.js to get the same information?

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76
Daniele Ricci
  • 15,422
  • 1
  • 27
  • 55
  • "current file descriptor position can be changed right before any `fs.read` or `fs.write` by the argument `position`": *Except* "On Linux, positional writes don't work when the file is opened in append mode. The kernel ignores the position argument and always appends the data to the end of the file." – Azeem Aug 08 '20 at 05:27
  • BTW, how do want to utilize the offset returned by `lseek`? What is the use-case? – Azeem Aug 08 '20 at 05:30
  • 1
    Nothing specific @Azeem ; I wrote [rotating-file-stream](https://www.npmjs.com/package/rotating-file-stream), a simple Node.js package for log rotation and thinking to new features I thought this could be an useful info. And thank you for the clarification in your first comment – Daniele Ricci Aug 10 '20 at 16:12
  • Maybe this can be useful to you [how-to-get-current-offset-of-stream-or-file-descriptor](https://stackoverflow.com/questions/60237517/how-to-get-current-offset-of-stream-or-file-descriptor) – Luis Paulo Pinto Aug 12 '20 at 12:52
  • @Azeem One use-case would be when reading (huge) files and one want to navigate back and forth. For example one can have a file with headers / sections that give relative offsets. I.e. read header at offset 0, it say `you find section x of size 512 at offset 12345`, Section x say you'll find block y at at relative offset +6332, -334 etc ... One can of course keep track manually, but makes for one more place to introduce a bug + makes abstraction harder in some cases. – user3342816 May 06 '23 at 10:18

3 Answers3

3

It seems there's no "native" way for this. Probably because of

It is unsafe to use fs.write***() multiple times on the same file without waiting for the callback.

It would be even more so with something like getCurrentPosition for a buffered IO. What it should return after write*** or read*** but before the callback is called?

But you can try and keep track of the current position yourself with the help of bytesRead and bytesWritten. And in case of streams there is chunk.length, but don't forget about encodings in case of strings.


As a side note... you've wrote:

thinking to new features I thought this could be an useful info

If no one requested it, and you yourself is not sure what it can be used for, then I think it's a good idea to exercise YAGNI principle.

x00
  • 13,643
  • 3
  • 16
  • 40
1

I strongly suspect that, at low level, the argument position is handled with an lseek call before the read or write operation, but what about the return value of lseek?

It is not used under the hood as said by Ben Noordhuis (libuv maintainer) :

lseek() is unpredictable with concurrent readers or writers. The libuv way is to use positional reads and writes (the offset argument to uv_fs_read() and uv_fs_write().)

This issue on node.js GitHub talk about how they manage the position argument to read and write data into the file.

Is there a way in Node.js to get the same information?

The accepted answer explain well how to do that: you need to track the read and written bytes.

Manuel Spigolon
  • 11,003
  • 5
  • 50
  • 73
-1

In Node.js you can use fs.read() and fs.write() for same.

Node can tell you where in the file system it is working by using the _filename and _dirname variables. The filename variable provides the absolute path to the file that is currently executing; dirname provides the absolute path to the working directory where the file being executed is located. Neither variable has to be imported from any modules because each is provided standard.

A simple example using both variables appears below:

console.log("This file is " +__filename); console.log("It's located in " +__dirname);

Viral Patel
  • 1,104
  • 4
  • 7