diff --git a/README.md b/README.md index 1b3b4a4..6f7304e 100644 --- a/README.md +++ b/README.md @@ -175,7 +175,7 @@ interface as providers. See the code in `src/providers` and `src/adapters` for The node.js [path module](http://nodejs.org/api/path.html) is available via the `Filer.Path` object. It is identical to the node.js version with the following differences: -* No support for `exits()` or `existsSync()`. Use `fs.stat()` instead. +* No support for `existsSync()`. Use `fs.stat()` instead. * No notion of a current working directory in `resolve` (the root dir is used instead) ```javascript @@ -219,6 +219,7 @@ var fs = new Filer.FileSystem(); * [fs.stat(path, callback)](#stat) * [fs.fstat(fd, callback)](#fstat) * [fs.lstat(path, callback)](#lstat) +* [fs.exists(path, callback)](#exists) * [fs.link(srcpath, dstpath, callback)](#link) * [fs.symlink(srcpath, dstpath, [type], callback)](#symlink) * [fs.readlink(path, callback)](#readlink) @@ -417,7 +418,25 @@ fs.link("/data/logs/august", "/data/logs/current", function(err) { var size = stats.size; }); }); -```` +``` + +#### fs.exists(path, callback) + +Test whether or not the given path exists by checking with the file system. +Then call the callback argument with either true or false. + +Example: + +```javascript +//Test if the file exists +fs.exists('/myfile', function (exists) { + console.log(exists ? "file exists" : "file not found"); +}); +``` + +fs.exists() is an anachronism and exists only for historical reasons. There should almost never be a reason to use it in your own code. + +In particular, checking if a file exists before opening it is an anti-pattern that leaves you vulnerable to race conditions: another process may remove the file between the calls to fs.exists() and fs.open(). Just open the file and handle the error when it's not there. #### fs.link(srcPath, dstPath, callback) diff --git a/src/fs.js b/src/fs.js index 122ce21..2bcf1d3 100644 --- a/src/fs.js +++ b/src/fs.js @@ -1789,6 +1789,13 @@ define(function(require) { }); } + function _exists (context, name, path, callback) { + function cb(err, stats) { + callback(err ? false : true); + } + _stat(context, name, path, cb); + } + function _getxattr (context, path, name, callback) { if (!nullCheck(path, callback)) return; @@ -2265,6 +2272,17 @@ define(function(require) { ); if(error) callback(error); }; + FileSystem.prototype.exists = function(path, callback_) { + var callback = maybeCallback(arguments[arguments.length - 1]); + var fs = this; + var error = fs.queueOrRun( + function() { + var context = fs.provider.getReadOnlyContext(); + _exists(context, fs.name, path, callback); + } + ); + if(error) callback(error); + }; FileSystem.prototype.lseek = function(fd, offset, whence, callback) { callback = maybeCallback(callback); var fs = this; diff --git a/tests/spec/fs.exists.spec.js b/tests/spec/fs.exists.spec.js new file mode 100644 index 0000000..ff8bc03 --- /dev/null +++ b/tests/spec/fs.exists.spec.js @@ -0,0 +1,56 @@ +define(["Filer", "util"], function(Filer, util) { + + describe('fs.exists', function() { + beforeEach(util.setup); + afterEach(util.cleanup); + + it('should be a function', function() { + var fs = util.fs(); + expect(typeof fs.exists).to.equal('function'); + }); + + it('should return false if path does not exist', function(done) { + var fs = util.fs(); + fs.exists('/tmp', function(result) { + expect(result).to.exist; + expect(result).equals(false); + done(); + }); + }); + + it('should return true if path exists', function(done) { + var fs = util.fs(); + + fs.open('/myfile', 'w', function(err, fd) { + if(err) throw err; + fs.close(fd, function(err) { + if(err) throw err; + fs.exists('/myfile', function(result) { + expect(result).to.exist; + expect(result).equals(true); + done(); + }); + }); + }); + }); + + it('should follow symbolic links and return true for the resulting path', function(done) { + var fs = util.fs(); + + fs.open('/myfile', 'w', function(error, fd) { + if(error) throw error; + fs.close(fd, function(error) { + if(error) throw error; + fs.symlink('/myfile', '/myfilelink', function(error) { + if(error) throw error; + fs.exists('/myfilelink', function(result) { + expect(result).to.exist; + expect(result).equals(true); + done(); + }); + }); + }); + }); + }); + }); +}); diff --git a/tests/test-manifest.js b/tests/test-manifest.js index 3b903a6..026c4b7 100644 --- a/tests/test-manifest.js +++ b/tests/test-manifest.js @@ -12,6 +12,7 @@ define([ "spec/fs.spec", "spec/fs.stat.spec", "spec/fs.lstat.spec", + "spec/fs.exists.spec", "spec/fs.mkdir.spec", "spec/fs.readdir.spec", "spec/fs.rmdir.spec",