File API tweaks
- Rename fs.cat to fs.readFile - Move file.write to fs.writeFile - Allow strings for the flag argument to fs.open ("r", "r+", "w", "w+", "a", "a+") - Remove the unused 'File' module / class
This commit is contained in:
Родитель
ae85d9af97
Коммит
6115df6338
20
doc/api.txt
20
doc/api.txt
|
@ -709,8 +709,10 @@ See the +fs.Stats+ section below for more information.
|
||||||
- on error: no parameters.
|
- 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+.
|
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 success: +fd+ is given as the parameter.
|
||||||
- on error: no parameters.
|
- 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 success: returns +data, bytes_read+, what was read from the file.
|
||||||
- on error: no parameters.
|
- on error: no parameters.
|
||||||
|
|
||||||
+fs.cat(filename, encoding="utf8")+::
|
+fs.readFile(filename, encoding="utf8")+::
|
||||||
Outputs the entire contents of a file. Example:
|
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);
|
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 success: returns +data+, what was read from the file.
|
||||||
- on error: no parameters.
|
- 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+
|
==== +fs.Stats+
|
||||||
|
|
||||||
Objects returned from +fs.stat()+ are of this type.
|
Objects returned from +fs.stat()+ are of this type.
|
||||||
|
|
157
lib/file.js
157
lib/file.js
|
@ -1,156 +1 @@
|
||||||
var fs = require("./fs");
|
throw new Error("The 'file' module has been removed. 'file.read' is now 'fs.readFile', and 'file.write' is now 'fs.writeFile'.");
|
||||||
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));
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
78
src/node.js
78
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
|
// Yes, the follow could be easily DRYed up but I provide the explicit
|
||||||
// list to make the arguments clear.
|
// list to make the arguments clear.
|
||||||
|
@ -541,13 +558,15 @@ var fsModule = createInternalModule("fs", function (exports) {
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.open = function (path, flags, mode) {
|
exports.open = function (path, flags, mode) {
|
||||||
|
if (mode === undefined) { mode = 0666; }
|
||||||
var promise = new events.Promise();
|
var promise = new events.Promise();
|
||||||
process.fs.open(path, flags, mode, callback(promise));
|
process.fs.open(path, stringToFlags(flags), mode, callback(promise));
|
||||||
return promise;
|
return promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.openSync = function (path, flags, mode) {
|
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) {
|
exports.read = function (fd, length, position, encoding) {
|
||||||
|
@ -654,13 +673,54 @@ var fsModule = createInternalModule("fs", function (exports) {
|
||||||
return process.fs.unlink(path);
|
return process.fs.unlink(path);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.writeFile = function (path, data, encoding) {
|
||||||
|
var promise = new events.Promise();
|
||||||
|
encoding = encoding || "utf8"; // default to utf8
|
||||||
|
|
||||||
exports.cat = function (path, encoding) {
|
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.readFile = function (path, encoding) {
|
||||||
var promise = new events.Promise();
|
var promise = new events.Promise();
|
||||||
|
|
||||||
encoding = encoding || "utf8"; // default to utf8
|
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;
|
var content = "", pos = 0;
|
||||||
|
|
||||||
function readChunk () {
|
function readChunk () {
|
||||||
|
@ -689,11 +749,15 @@ var fsModule = createInternalModule("fs", function (exports) {
|
||||||
return promise;
|
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
|
encoding = encoding || "utf8"; // default to utf8
|
||||||
|
|
||||||
var
|
var
|
||||||
fd = exports.openSync(path, process.O_RDONLY, 0666),
|
fd = exports.openSync(path, "r"),
|
||||||
content = '',
|
content = '',
|
||||||
pos = 0,
|
pos = 0,
|
||||||
r;
|
r;
|
||||||
|
@ -939,7 +1003,7 @@ function cat (id, loadPromise) {
|
||||||
loadPromise.emitError(new Error("could not load core module \"http\""));
|
loadPromise.emitError(new Error("could not load core module \"http\""));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
promise = fs.cat(id);
|
promise = fs.readFile(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return promise;
|
return promise;
|
||||||
|
|
|
@ -19,8 +19,8 @@ server.listen(PORT);
|
||||||
|
|
||||||
var client = tcp.createConnection(PORT);
|
var client = tcp.createConnection(PORT);
|
||||||
client.addListener("connect", function () {
|
client.addListener("connect", function () {
|
||||||
posix.open(x,process.O_RDONLY, 0666).addCallback(function (fd) {
|
fs.open(x, 'r').addCallback(function (fd) {
|
||||||
posix.sendfile(client.fd, fd, 0, expected.length).addCallback(function (size) {
|
fs.sendfile(client.fd, fd, 0, expected.length).addCallback(function (size) {
|
||||||
assert.equal(expected.length, size);
|
assert.equal(expected.length, size);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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");
|
|
||||||
});
|
|
|
@ -36,7 +36,7 @@ function tryToKillEventLoop() {
|
||||||
|
|
||||||
// Generate a lot of thread pool events
|
// Generate a lot of thread pool events
|
||||||
var pos = 0;
|
var pos = 0;
|
||||||
fs.open('/dev/zero', process.O_RDONLY, 0666).addCallback(function (rd) {
|
fs.open('/dev/zero', "r").addCallback(function (rd) {
|
||||||
function readChunk () {
|
function readChunk () {
|
||||||
fs.read(rd, 1024, pos, 'binary').addCallback(function (chunk, bytesRead) {
|
fs.read(rd, 1024, pos, 'binary').addCallback(function (chunk, bytesRead) {
|
||||||
if (chunk) {
|
if (chunk) {
|
||||||
|
|
|
@ -8,7 +8,7 @@ setTimeout(function () {
|
||||||
N = 30;
|
N = 30;
|
||||||
for (var i=0; i < N; i++) {
|
for (var i=0; i < N; i++) {
|
||||||
puts("start " + i);
|
puts("start " + i);
|
||||||
fs.cat(testTxt).addCallback(function(data) {
|
fs.readFile(testTxt).addCallback(function(data) {
|
||||||
puts("finish");
|
puts("finish");
|
||||||
}).addErrback(function (e) {
|
}).addErrback(function (e) {
|
||||||
puts("error! " + e);
|
puts("error! " + e);
|
||||||
|
|
|
@ -2,7 +2,7 @@ process.mixin(require("./common"));
|
||||||
var got_error = false;
|
var got_error = false;
|
||||||
|
|
||||||
var filename = path.join(fixturesDir, "does_not_exist.txt");
|
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) {
|
promise.addCallback(function (content) {
|
||||||
debug("cat returned some content: " + content);
|
debug("cat returned some content: " + content);
|
|
@ -4,10 +4,10 @@ var fn = path.join(fixturesDir, "write.txt");
|
||||||
var expected = "hello";
|
var expected = "hello";
|
||||||
var found;
|
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.write(file, expected, 0, "utf8").addCallback(function() {
|
||||||
fs.close(file).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;
|
found = contents;
|
||||||
fs.unlink(fn).wait();
|
fs.unlink(fn).wait();
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,12 +16,11 @@ process.watchFile(f, function (curr, prev) {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
var File = require("file").File;
|
var fs = require("fs");
|
||||||
|
|
||||||
var file = new File(f, 'w+');
|
|
||||||
file.write('xyz\n');
|
|
||||||
file.close().wait();
|
|
||||||
|
|
||||||
|
var fd = fs.openSync(f, "w+");
|
||||||
|
fs.writeSync(fd, 'xyz\n');
|
||||||
|
fs.closeSync(fd);
|
||||||
|
|
||||||
process.addListener("exit", function () {
|
process.addListener("exit", function () {
|
||||||
assert.equal(true, changes > 0);
|
assert.equal(true, changes > 0);
|
||||||
|
|
|
@ -2,4 +2,4 @@ process.mixin(require('./common'));
|
||||||
|
|
||||||
var fixture = path.join(__dirname, "fixtures/x.txt");
|
var fixture = path.join(__dirname, "fixtures/x.txt");
|
||||||
|
|
||||||
assert.equal("xyz\n", fs.catSync(fixture));
|
assert.equal("xyz\n", fs.readFileSync(fixture));
|
Загрузка…
Ссылка в новой задаче