Browse Source

Don't use stat in fs.readFile[Sync]

Original patch c/o Evan Larkin <evan.larkin.iit@gmail.com>
v0.7.4-release
isaacs 14 years ago
committed by Ryan Dahl
parent
commit
4d0456f827
  1. 114
      lib/fs.js
  2. 9
      test/simple/test-fs-read-file-sync-hostname.js

114
lib/fs.js

@ -43,71 +43,83 @@ fs.Stats.prototype.isSocket = function () {
return this._checkModeProperty(constants.S_IFSOCK); return this._checkModeProperty(constants.S_IFSOCK);
}; };
fs.readFile = function (path, encoding_, callback) { fs.readFile = function (path, encoding_) {
var encoding = typeof(encoding_) == 'string' ? encoding_ : null; var encoding = typeof(encoding_) === 'string' ? encoding_ : null;
var callback_ = arguments[arguments.length - 1]; var callback = arguments[arguments.length-1];
var callback = (typeof(callback_) == 'function' ? callback_ : noop); if (typeof(callback) !== 'function') callback = noop;
binding.stat(path, function (err, stat) { var readStream = fs.createReadStream(path);
if (err) { callback(err); return; } var buffers = [];
binding.open(path, constants.O_RDONLY, 0666, function (err, fd) { var nread = 0;
if (err) { callback(err); return; } readStream.on("data", function (chunk) {
var size = stat.size; buffers.push(chunk);
var buffer = new Buffer(size); nread += chunk.length;
var offset = 0; });
function doRead() { readStream.on("error", function (er) {
if (size < 1) { callback(er);
binding.close(fd); readStream.destroy();
callback(null, encoding ? '' : buffer); });
return; readStream.on("end", function () {
} // copy all the buffers into one
// position is offset or null so we can read files on unseekable mediums var buffer;
binding.read(fd, buffer, offset, size - offset, offset || null, function (err, amount) { switch (buffers.length) {
if (err) { case 0: buffer = new Buffer(0); break;
callback(err); case 1: buffer = buffers[0]; break;
binding.close(fd); default: // concat together
return; buffer = new Buffer(nread);
} var n = 0;
if (amount + offset < size) { buffers.forEach(function (b) {
offset += amount; var l = b.length;
doRead(); b.copy(buffer, n, 0, l);
return; n += l;
}
binding.close(fd);
if (encoding) {
try {
var str = buffer.toString(encoding);
} catch (err) {
callback(err);
return;
}
callback(null, str);
} else {
callback(null, buffer);
}
}); });
break;
}
if (encoding) {
try {
buffer = buffer.toString(encoding);
} catch (er) {
return callback(er);
} }
doRead(); }
}); callback(null, buffer);
}); });
}; };
fs.readFileSync = function (path, encoding) { fs.readFileSync = function (path, encoding) {
var fd = fs.openSync(path, constants.O_RDONLY, 0666); var fd = fs.openSync(path, constants.O_RDONLY, 0666);
var stat = fs.statSync(path); var buffer = new Buffer(4048);
var buffer = new Buffer(stat.size); var buffers = [];
var nread = 0; var nread = 0;
var lastRead = 0;
while (nread < buffer.length) { do {
nread += fs.readSync(fd, buffer, nread, buffer.length - nread, null); if (lastRead) {
} buffer._bytesRead = lastRead;
nread += lastRead;
buffers.push(buffer);
}
var buffer = new Buffer(4048);
lastRead = fs.readSync(fd, buffer, 0, buffer.length, null);
} while (lastRead > 0);
fs.closeSync(fd); fs.closeSync(fd);
if (encoding) { if (buffers.length > 1) {
return buffer.toString(encoding); var offset = 0;
var i;
buffer = new Buffer(nread);
buffers.forEach(function (i) {
if (!i._bytesRead) return;
i.copy(buffer,offset,0,i._bytesRead);
offset += i._bytesRead;
})
} else { } else {
return buffer; //buffers has exactly 1 (possibly zero length) buffer, so this should be a shortcut
buffer = buffers[0].slice(0, buffers[0]._bytesRead);
} }
if (encoding) buffer = buffer.toString(encoding);
return buffer;
}; };

9
test/simple/test-fs-read-file-sync-hostname.js

@ -0,0 +1,9 @@
common = require("../common");
assert = common.assert
var fs = require('fs');
// test reading from hostname
if (process.platform === "linux2") {
var hostname = fs.readFileSync('/proc/sys/kernel/hostname');
assert.ok(hostname.length > 0);
}
Loading…
Cancel
Save