7

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.

soyuka
  • 8,839
  • 3
  • 39
  • 54
  • 1
    Why do not you use the argument "position" functions read / write? – stdob-- Jul 24 '15 at 09:52
  • 1
    I don't need them, I'm using [this function](https://nodejs.org/api/fs.html#fs_fs_write_fd_data_position_encoding_callback) to write and `position` argument is optional. I just want to write some data in a file and get back a file descriptor with a cursor at position 0. – soyuka Jul 24 '15 at 10:06

3 Answers3

1

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.

Community
  • 1
  • 1
soyuka
  • 8,839
  • 3
  • 39
  • 54
  • 1
    fs-ext appears to be broken under v4.1.1. – David G Sep 29 '15 at 03:55
  • Indeed, and it [won't work with 4.0 either](https://github.com/baudehlo/node-fs-ext/issues/51). I'm still using my workaround. – soyuka Sep 29 '15 at 06:40
  • After further investigation and talking with the maintainer, the problem is with Nan2.0 (which has changed considerably under v4.0+). The repo has been branched to support this and can be installed with npm directly from github until the changes are merged back to mainline. `npm install -g git+https://github.com/ggreer/node-fs-ext.git#nan_2` – David G Sep 30 '15 at 15:43
1

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.

D. Visser
  • 875
  • 2
  • 12
  • 19
  • 1
    This has nothing to do with streams but more about controlling the file cursor pointer. More specifically, it's a binding to [`lseek`](http://man7.org/linux/man-pages/man2/lseek.2.html) (in fs-ext for example). – soyuka Sep 08 '16 at 13:04
  • 1
    I agree. I would like to see a solution for this as well, but this has been my workaround for now. – D. Visser Sep 08 '16 at 13:07
  • `start` and `end` are byte offsets, not line number. Ref: https://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options – Alex Ilyaev Nov 18 '17 at 17:45
0

fs.write might be helpful here:

  1. fs.open to get fd
  2. fs.write(fd, string, position)
  3. fs.close(fd)
clarkttfu
  • 577
  • 6
  • 11