diff --git a/lib/fs.js b/lib/fs.js index 705d2232b3..24259c02fb 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -43,71 +43,83 @@ fs.Stats.prototype.isSocket = function () { return this._checkModeProperty(constants.S_IFSOCK); }; -fs.readFile = function (path, encoding_, callback) { - var encoding = typeof(encoding_) == 'string' ? encoding_ : null; - var callback_ = arguments[arguments.length - 1]; - var callback = (typeof(callback_) == 'function' ? callback_ : noop); - binding.stat(path, function (err, stat) { - if (err) { callback(err); return; } - binding.open(path, constants.O_RDONLY, 0666, function (err, fd) { - if (err) { callback(err); return; } - var size = stat.size; - var buffer = new Buffer(size); - var offset = 0; - function doRead() { - if (size < 1) { - binding.close(fd); - callback(null, encoding ? '' : buffer); - return; - } - // 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) { - try { - var str = buffer.toString(encoding); - } catch (err) { - callback(err); - return; - } - callback(null, str); - } else { - callback(null, buffer); - } +fs.readFile = function (path, encoding_) { + var encoding = typeof(encoding_) === 'string' ? encoding_ : null; + var callback = arguments[arguments.length-1]; + if (typeof(callback) !== 'function') callback = noop; + var readStream = fs.createReadStream(path); + var buffers = []; + var nread = 0; + readStream.on("data", function (chunk) { + buffers.push(chunk); + nread += chunk.length; + }); + readStream.on("error", function (er) { + callback(er); + readStream.destroy(); + }); + 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; + } + if (encoding) { + try { + buffer = buffer.toString(encoding); + } catch (er) { + return callback(er); } - doRead(); - }); + } + callback(null, buffer); }); }; fs.readFileSync = function (path, encoding) { var fd = fs.openSync(path, constants.O_RDONLY, 0666); - var stat = fs.statSync(path); - var buffer = new Buffer(stat.size); + var buffer = new Buffer(4048); + var buffers = []; var nread = 0; + var lastRead = 0; - while (nread < buffer.length) { - nread += fs.readSync(fd, buffer, nread, buffer.length - nread, null); - } + do { + 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); - if (encoding) { - return buffer.toString(encoding); + if (buffers.length > 1) { + 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 { - 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; }; diff --git a/test/simple/test-fs-read-file-sync-hostname.js b/test/simple/test-fs-read-file-sync-hostname.js new file mode 100644 index 0000000000..1929ac8bcd --- /dev/null +++ b/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); +}