Don't use stat in fs.readFile[Sync]
Original patch c/o Evan Larkin <evan.larkin.iit@gmail.com>
This commit is contained in:
parent
4df999f85f
commit
4d0456f827
106
lib/fs.js
106
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
|
||||||
|
var buffer;
|
||||||
|
switch (buffers.length) {
|
||||||
|
case 0: buffer = new Buffer(0); break;
|
||||||
|
case 1: buffer = buffers[0]; break;
|
||||||
|
default: // concat together
|
||||||
|
buffer = new Buffer(nread);
|
||||||
|
var n = 0;
|
||||||
|
buffers.forEach(function (b) {
|
||||||
|
var l = b.length;
|
||||||
|
b.copy(buffer, n, 0, l);
|
||||||
|
n += l;
|
||||||
|
});
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
// position is offset or null so we can read files on unseekable mediums
|
|
||||||
binding.read(fd, buffer, offset, size - offset, offset || null, function (err, amount) {
|
|
||||||
if (err) {
|
|
||||||
callback(err);
|
|
||||||
binding.close(fd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (amount + offset < size) {
|
|
||||||
offset += amount;
|
|
||||||
doRead();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
binding.close(fd);
|
|
||||||
if (encoding) {
|
if (encoding) {
|
||||||
try {
|
try {
|
||||||
var str = buffer.toString(encoding);
|
buffer = buffer.toString(encoding);
|
||||||
} catch (err) {
|
} catch (er) {
|
||||||
callback(err);
|
return callback(er);
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
callback(null, str);
|
|
||||||
} else {
|
|
||||||
callback(null, buffer);
|
callback(null, buffer);
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
doRead();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
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
Normal file
9
test/simple/test-fs-read-file-sync-hostname.js
Normal file
@ -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…
x
Reference in New Issue
Block a user