diff --git a/doc/api.txt b/doc/api.txt index bc1fe9f681..9ddca51b92 100644 --- a/doc/api.txt +++ b/doc/api.txt @@ -709,8 +709,10 @@ See the +fs.Stats+ section below for more information. - on error: no parameters. -+fs.open(path, flags, mode)+:: ++fs.open(path, flags, mode=0666)+:: See open(2). The constants like +O_CREAT+ are defined at +process.O_CREAT+. + Also you can use the strings "r", "r+", "w", "w+", "a", or "a+" as aliases + to the common flag combinations. - on success: +fd+ is given as the parameter. - on error: no parameters. @@ -735,11 +737,11 @@ See the +fs.Stats+ section below for more information. - on success: returns +data, bytes_read+, what was read from the file. - on error: no parameters. -+fs.cat(filename, encoding="utf8")+:: ++fs.readFile(filename, encoding="utf8")+:: Outputs the entire contents of a file. Example: + -------------------------------- -fs.cat("/etc/passwd").addCallback(function (content) { +fs.readFile("/etc/passwd").addCallback(function (content) { sys.puts(content); }); -------------------------------- @@ -747,6 +749,18 @@ fs.cat("/etc/passwd").addCallback(function (content) { - on success: returns +data+, what was read from the file. - on error: no parameters. ++fs.writeFile(filename, data, encoding="utf8")+:: +Writes data to a file. Example: ++ +-------------------------------- +fs.writeFile("message.txt", "Hello Node").addCallback(function () { + sys.puts("It's saved!"); +}); +-------------------------------- ++ +- on success: no parameters. +- on error: no parameters. + ==== +fs.Stats+ Objects returned from +fs.stat()+ are of this type. diff --git a/lib/file.js b/lib/file.js index c024f54578..d8c1a6c7c2 100644 --- a/lib/file.js +++ b/lib/file.js @@ -1,156 +1 @@ -var fs = require("./fs"); -var events = require('events'); -/*jslint onevar: true, undef: true, eqeqeq: true, plusplus: true, regexp: true, newcap: true, immed: true */ -/*globals exports, node, __filename */ - -exports.debugLevel = 0; // Increase to get more verbose debug output - -function debugMessage (msg) { - if (exports.debugLevel > 0) { - process.error(__filename + ": " + msg.toString()); - } -} - -function debugObject (obj) { - if (exports.debugLevel > 0) { - process.error(__filename + ": " + JSON.stringify(obj)); - } -} - -exports.read = fs.cat; - -exports.write = function (filename, data, encoding) { - var promise = new events.Promise(); - - encoding = encoding || "utf8"; // default to utf8 - - fs.open(filename, process.O_WRONLY | process.O_TRUNC | process.O_CREAT, 0666) - .addCallback(function (fd) { - function doWrite (_data) { - fs.write(fd, _data, 0, encoding) - .addErrback(function () { - fs.close(fd); - promise.emitError(); - }) - .addCallback(function (written) { - if (written === _data.length) { - fs.close(fd); - promise.emitSuccess(); - } else { - doWrite(_data.slice(written)); - } - }); - } - doWrite(data); - }) - .addErrback(function () { - promise.emitError(); - }); - - return promise; -}; - -exports.File = function (filename, mode, options) { - var self = this; - - options = options || {}; - self.encoding = options.encoding || "utf8"; - - self.filename = filename; - - self.actionQueue = []; - self.currentAction = null; - - switch (mode) { - case "r": - self.flags = process.O_RDONLY; - break; - - case "r+": - self.flags = process.O_RDWR; - break; - - case "w": - self.flags = process.O_CREAT | process.O_TRUNC | process.O_WRONLY; - break; - - case "w+": - self.flags = process.O_CREAT | process.O_TRUNC | process.O_RDWR; - break; - - case "a": - self.flags = process.O_APPEND | process.O_CREAT | process.O_WRONLY; - break; - - case "a+": - self.flags = process.O_APPEND | process.O_CREAT | process.O_RDWR; - break; - - default: - throw new Error("Unknown mode"); - } - - self.open(self.filename, self.flags, 0666).addCallback(function (fd) { - debugMessage(self.filename + " opened. fd = " + fd); - self.fd = fd; - }).addErrback(function () { - self.emit("error", ["open"]); - }); -}; - -var proto = exports.File.prototype; - -proto._maybeDispatch = function () { - var self, args, method, promise, userPromise; - - self = this; - - if (self.currentAction) { return; } - self.currentAction = self.actionQueue.shift(); - if (!self.currentAction) { return; } - - debugObject(self.currentAction); - - args = self.currentAction.args || []; - method = self.currentAction.method; - - - if (method !== "open") { - args.unshift(self.fd); - } - - if (!args[3] && (method === "read" || method === "write")) { - args[3] = self.encoding; - } - promise = fs[method].apply(self, args); - - userPromise = self.currentAction.promise; - - promise.addCallback(function () { - process.assert(self.currentAction.promise === userPromise); - userPromise.emitSuccess.apply(userPromise, arguments); - self.currentAction = null; - self._maybeDispatch(); - }).addErrback(function () { - debugMessage("Error in method " + method); - process.assert(self.currentAction.promise === userPromise); - userPromise.emitError.apply(userPromise, arguments); - self.currentAction = null; - self._maybeDispatch(); - }); -}; - -proto._queueAction = function (method, args) { - var userPromise = new events.Promise(); - this.actionQueue.push({ method: method, args: args, promise: userPromise }); - this._maybeDispatch(); - return userPromise; -}; - - -(["open", "write", "read", "close"]).forEach(function (name) { - proto[name] = function () { - return this._queueAction(name, Array.prototype.slice.call(arguments, 0)); - }; -}); - +throw new Error("The 'file' module has been removed. 'file.read' is now 'fs.readFile', and 'file.write' is now 'fs.writeFile'."); diff --git a/src/node.js b/src/node.js index 905757cd41..302790f41d 100644 --- a/src/node.js +++ b/src/node.js @@ -526,6 +526,23 @@ var fsModule = createInternalModule("fs", function (exports) { } }; } + + // Used by fs.open and friends + function stringToFlags(flag) { + // Only mess with strings + if (typeof flag !== 'string') { + return flag; + } + switch (flag) { + case "r": return process.O_RDONLY; + case "r+": return process.O_RDWR; + case "w": return process.O_CREAT | process.O_TRUNC | process.O_WRONLY; + case "w+": return process.O_CREAT | process.O_TRUNC | process.O_RDWR; + case "a": return process.O_APPEND | process.O_CREAT | process.O_WRONLY; + case "a+": return process.O_APPEND | process.O_CREAT | process.O_RDWR; + default: throw new Error("Unknown file open flag: " + flag); + } + } // Yes, the follow could be easily DRYed up but I provide the explicit // list to make the arguments clear. @@ -541,13 +558,15 @@ var fsModule = createInternalModule("fs", function (exports) { }; exports.open = function (path, flags, mode) { + if (mode === undefined) { mode = 0666; } var promise = new events.Promise(); - process.fs.open(path, flags, mode, callback(promise)); + process.fs.open(path, stringToFlags(flags), mode, callback(promise)); return promise; }; exports.openSync = function (path, flags, mode) { - return process.fs.open(path, flags, mode); + if (mode === undefined) { mode = 0666; } + return process.fs.open(path, stringToFlags(flags), mode); }; exports.read = function (fd, length, position, encoding) { @@ -654,13 +673,54 @@ var fsModule = createInternalModule("fs", function (exports) { return process.fs.unlink(path); }; + exports.writeFile = function (path, data, encoding) { + var promise = new events.Promise(); + encoding = encoding || "utf8"; // default to utf8 + + fs.open(path, "w") + .addCallback(function (fd) { + function doWrite (_data) { + fs.write(fd, _data, 0, encoding) + .addErrback(function () { + fs.close(fd); + promise.emitError(); + }) + .addCallback(function (written) { + if (written === _data.length) { + fs.close(fd); + promise.emitSuccess(); + } else { + doWrite(_data.slice(written)); + } + }); + } + doWrite(data); + }) + .addErrback(function () { + promise.emitError(); + }); + + return promise; + + }; + + exports.writeFileSync = function (path, data, encoding) { + encoding = encoding || "utf8"; // default to utf8 + var fd = exports.openSync(path, "w"); + return process.fs.write(fd, data, 0, encoding); + }; + + + exports.cat = function () { + throw new Error("fs.cat is deprecated. Please use fs.readFile instead."); + }; - exports.cat = function (path, encoding) { + exports.readFile = function (path, encoding) { var promise = new events.Promise(); encoding = encoding || "utf8"; // default to utf8 - exports.open(path, process.O_RDONLY, 0666).addCallback(function (fd) { + exports.open(path, "r").addCallback(function (fd) { var content = "", pos = 0; function readChunk () { @@ -689,11 +749,15 @@ var fsModule = createInternalModule("fs", function (exports) { return promise; }; - exports.catSync = function (path, encoding) { + exports.catSync = function () { + throw new Error("fs.catSync is deprecated. Please use fs.readFileSync instead."); + }; + + exports.readFileSync = function (path, encoding) { encoding = encoding || "utf8"; // default to utf8 var - fd = exports.openSync(path, process.O_RDONLY, 0666), + fd = exports.openSync(path, "r"), content = '', pos = 0, r; @@ -939,7 +1003,7 @@ function cat (id, loadPromise) { loadPromise.emitError(new Error("could not load core module \"http\"")); }); } else { - promise = fs.cat(id); + promise = fs.readFile(id); } return promise; diff --git a/test/mjsunit/disabled/test-fs-sendfile.js b/test/mjsunit/disabled/test-fs-sendfile.js index 93cac12ca2..41e16dffcf 100644 --- a/test/mjsunit/disabled/test-fs-sendfile.js +++ b/test/mjsunit/disabled/test-fs-sendfile.js @@ -19,8 +19,8 @@ server.listen(PORT); var client = tcp.createConnection(PORT); client.addListener("connect", function () { - posix.open(x,process.O_RDONLY, 0666).addCallback(function (fd) { - posix.sendfile(client.fd, fd, 0, expected.length).addCallback(function (size) { + fs.open(x, 'r').addCallback(function (fd) { + fs.sendfile(client.fd, fd, 0, expected.length).addCallback(function (size) { assert.equal(expected.length, size); }); }); diff --git a/test/mjsunit/test-buffered-file.js b/test/mjsunit/test-buffered-file.js deleted file mode 100644 index dbea229715..0000000000 --- a/test/mjsunit/test-buffered-file.js +++ /dev/null @@ -1,38 +0,0 @@ -process.mixin(require("./common")); - -var testTxt = path.join(fixturesDir, "test.txt"); - -var libDir = path.join(testDir, "../../lib"); -require.paths.unshift(libDir); -process.mixin(require("file")); - -var fileUnlinked = false; - -var file = new File(testTxt, "w+"); -file.write("hello\n"); -file.write("world\n"); -setTimeout(function () { - file.write("hello\n"); - file.write("world\n"); - file.close().addCallback(function () { - error("file closed..."); - var out = fs.cat(testTxt).wait(); - print("the file contains: "); - p(out); - assert.equal("hello\nworld\nhello\nworld\n", out); - var file2 = new File(testTxt, "r"); - file2.read(5).addCallback(function (data) { - puts("read(5): " + JSON.stringify(data)); - assert.equal("hello", data); - fs.unlink(testTxt).addCallback(function () { - fileUnlinked = true; - }); - }); - file2.close(); - }); -}, 10); - -process.addListener("exit", function () { - assert.equal(true, fileUnlinked); - puts("done"); -}); diff --git a/test/mjsunit/test-eio-race.js b/test/mjsunit/test-eio-race.js index 20eb3825f2..cae4bc7405 100644 --- a/test/mjsunit/test-eio-race.js +++ b/test/mjsunit/test-eio-race.js @@ -36,7 +36,7 @@ function tryToKillEventLoop() { // Generate a lot of thread pool events var pos = 0; -fs.open('/dev/zero', process.O_RDONLY, 0666).addCallback(function (rd) { +fs.open('/dev/zero', "r").addCallback(function (rd) { function readChunk () { fs.read(rd, 1024, pos, 'binary').addCallback(function (chunk, bytesRead) { if (chunk) { diff --git a/test/mjsunit/test-eio-race2.js b/test/mjsunit/test-eio-race2.js index 5e904f2253..d11f5beb63 100644 --- a/test/mjsunit/test-eio-race2.js +++ b/test/mjsunit/test-eio-race2.js @@ -8,7 +8,7 @@ setTimeout(function () { N = 30; for (var i=0; i < N; i++) { puts("start " + i); - fs.cat(testTxt).addCallback(function(data) { + fs.readFile(testTxt).addCallback(function(data) { puts("finish"); }).addErrback(function (e) { puts("error! " + e); diff --git a/test/mjsunit/test-file-cat-noexist.js b/test/mjsunit/test-file-read-noexist.js similarity index 91% rename from test/mjsunit/test-file-cat-noexist.js rename to test/mjsunit/test-file-read-noexist.js index d11e002169..9e2b2ae0d0 100644 --- a/test/mjsunit/test-file-cat-noexist.js +++ b/test/mjsunit/test-file-read-noexist.js @@ -2,7 +2,7 @@ process.mixin(require("./common")); var got_error = false; var filename = path.join(fixturesDir, "does_not_exist.txt"); -var promise = fs.cat(filename, "raw"); +var promise = fs.readFile(filename, "raw"); promise.addCallback(function (content) { debug("cat returned some content: " + content); diff --git a/test/mjsunit/test-fs-write.js b/test/mjsunit/test-fs-write.js index f8074d5bf4..198c932b0d 100644 --- a/test/mjsunit/test-fs-write.js +++ b/test/mjsunit/test-fs-write.js @@ -4,10 +4,10 @@ var fn = path.join(fixturesDir, "write.txt"); var expected = "hello"; var found; -fs.open(fn, process.O_WRONLY | process.O_TRUNC | process.O_CREAT, 0644).addCallback(function (file) { +fs.open(fn, 'w', 0644).addCallback(function (file) { fs.write(file, expected, 0, "utf8").addCallback(function() { fs.close(file).addCallback(function() { - fs.cat(fn, process.UTF8).addCallback(function(contents) { + fs.readFile(fn, process.UTF8).addCallback(function(contents) { found = contents; fs.unlink(fn).wait(); }); diff --git a/test/mjsunit/test-stat-handler.js b/test/mjsunit/test-stat-handler.js index 4604c422df..ee3cd8b561 100644 --- a/test/mjsunit/test-stat-handler.js +++ b/test/mjsunit/test-stat-handler.js @@ -16,12 +16,11 @@ process.watchFile(f, function (curr, prev) { }); -var File = require("file").File; - -var file = new File(f, 'w+'); -file.write('xyz\n'); -file.close().wait(); +var fs = require("fs"); +var fd = fs.openSync(f, "w+"); +fs.writeSync(fd, 'xyz\n'); +fs.closeSync(fd); process.addListener("exit", function () { assert.equal(true, changes > 0); diff --git a/test/mjsunit/test-sync-cat.js b/test/mjsunit/test-sync-fileread.js similarity index 65% rename from test/mjsunit/test-sync-cat.js rename to test/mjsunit/test-sync-fileread.js index a602b1a151..bc80eec690 100644 --- a/test/mjsunit/test-sync-cat.js +++ b/test/mjsunit/test-sync-fileread.js @@ -2,4 +2,4 @@ process.mixin(require('./common')); var fixture = path.join(__dirname, "fixtures/x.txt"); -assert.equal("xyz\n", fs.catSync(fixture)); \ No newline at end of file +assert.equal("xyz\n", fs.readFileSync(fixture)); \ No newline at end of file