Search code examples
node.jsiocoffeescripttouchlibuv

Touch file then write to it in Node


How do I touch a file before writing to it?

Attempt

fs   = require 'fs'
os   = require 'os'
path = require 'path'


json_filepath = path.join os.tempdir(), 'cache', 'foo.json'

module.exports = (cb) ->
    fs.open json_filepath, 'w', 438, (err) -> # Touch, also tried with node-touch
        return cb err if err?
        fs.writeFile json_filepath, {foo: 'bar'}, {}, (err) ->
            #console.error 'Error writing cache: ', err
            cb err

Error

{ [Error: ENOENT, open '/tmp/cache/foo.json']
  errno: 34,
  code: 'ENOENT',
  path: '/tmp/cache/foo.json' }

Which is a POSIX error (linux manpage, additionally implemented for Windows, e.g.: in libuv). It means: No such file or directory


Solution

  • Why are you trying to open a file before calling fs.writeFile()? That is the wrong procedure and is likely causing at least part of your problem.

    You should JUST call fs.writeFile(). That will create the file, write to it and close it all in one call. Opening the file first in w mode will likely cause a conflict with fs.writeFile() since the file is already open for writing elsewhere. Further, you never close the file you opened, thus leaking a file handle.

    Just call fs.writeFile() with no fs.open() beforehand. That's how fs.writeFile() is written to work. One function call to do it all.

    If you still get ENOENT after removing the fs.open() and you've cleared any orphaned file handles, then the remaining issue is likely that your path doesn't exist or you don't have the proper privileges on that path.

    FYI, the path specified by:

    path.join(os.tempdir(), "cache")
    

    will not automatically exist. That would have to be something you created.