Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to rewind a file descriptor cursor in nodejs?

This is what I would do in a perfect world:

fs.open('somepath', 'r+', function(err, fd) {
    fs.write(fd, 'somedata', function(err, written, string) {
       fs.rewind(fd, 0) //this doesn't exist
    })
})

This is my current implementation:

return async.waterfall([
    function(next) {
      //opening a file descriptor to write some data
      return fs.open('somepath', 'w+', next)
    }, 
    function(fd, next) {
      //writing the data
      return fs.write(fd, 'somedata', function(err, written, string) {
        return next(null, fd)
      })
    },
    function(fd, next) {
      //closing the file descriptor
      return fs.close(fd, next)
    },
    function(next) {
      //open again to reset cursor position
      return fs.open('somepath', 'r', next)
    }
], function(err, fd) { 
   //fd cursor is now at beginning of the file 
})

I tried to reset the position without closing the fd by using:

fs.read(fd, new Buffer(0), 0, 0, 0, fn)

but this throws Error: Offset is out of bounds.

Is there a way to reset the cursor without doing this horrible hack?

/e: The offset is out of bounds error comes from this exception. Easily fixed by setting a buffer size to 1 but it does not rewind the cursor. Maybe because we ask the function to read nothing.

like image 690
soyuka Avatar asked Jul 24 '15 09:07

soyuka


2 Answers

Today, the answer is that it's not in the core, and that it can't be added with pure javascript.

There is an extension node-fs-ext that adds a seek function to move the fd cursor. This is done in C++ here.

Related Stackoverflow question.

like image 109
soyuka Avatar answered Nov 07 '22 02:11

soyuka


NodeJS v6.5.0 has the createReadStream method which accepts an array of options. Among those options are the start and end properties. These properties determine from and to which byte should be read, respectively.

So, if you set start to 0, it will read the file from the first byte. Leaving end empty in that case will cause the stream to read the file all the way to the end.

As an example:

fs.createReadStream('myfile.txt', {start: 0})

Using this read stream would allow you to read the whole file.

like image 1
D. Visser Avatar answered Nov 07 '22 03:11

D. Visser