|
|
@ -103,93 +103,88 @@ 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; |
|
|
|
var error; |
|
|
|
|
|
|
|
readStream.on('data', function(chunk) { |
|
|
|
buffers.push(chunk); |
|
|
|
nread += chunk.length; |
|
|
|
}); |
|
|
|
|
|
|
|
readStream.on('error', function(er) { |
|
|
|
error = er; |
|
|
|
readStream.destroy(); |
|
|
|
if (!readStream.fd) { |
|
|
|
readStream.emit('close'); |
|
|
|
} |
|
|
|
// first, stat the file, so we know the size.
|
|
|
|
var size; |
|
|
|
var buffer; |
|
|
|
var pos = 0; |
|
|
|
var fd; |
|
|
|
|
|
|
|
fs.open(path, constants.O_RDONLY, 438 /*=0666*/, function(er, fd_) { |
|
|
|
if (er) return callback(er); |
|
|
|
fd = fd_; |
|
|
|
|
|
|
|
fs.fstat(fd, function(er, st) { |
|
|
|
if (er) return callback(er); |
|
|
|
size = st.size; |
|
|
|
if (size === 0) { |
|
|
|
buffer = new Buffer(0); |
|
|
|
return afterRead(null, 0); |
|
|
|
} |
|
|
|
|
|
|
|
buffer = new Buffer(size); |
|
|
|
read(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
readStream.on('close', function() { |
|
|
|
if (error) { |
|
|
|
return callback(error); |
|
|
|
} |
|
|
|
function read() { |
|
|
|
fs.read(fd, buffer, pos, size - pos, pos, afterRead); |
|
|
|
} |
|
|
|
|
|
|
|
// 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) { |
|
|
|
function afterRead(er, bytesRead) { |
|
|
|
if (er) { |
|
|
|
return fs.close(fd, function(er2) { |
|
|
|
return callback(er); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
callback(null, buffer); |
|
|
|
}); |
|
|
|
|
|
|
|
pos += bytesRead; |
|
|
|
if (pos === size) close(); |
|
|
|
else read(); |
|
|
|
} |
|
|
|
|
|
|
|
function close() { |
|
|
|
fs.close(fd, function(er) { |
|
|
|
if (encoding) buffer = buffer.toString(encoding); |
|
|
|
return callback(er, buffer); |
|
|
|
}); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
fs.readFileSync = function(path, encoding) { |
|
|
|
var fd = fs.openSync(path, constants.O_RDONLY, 438 /*=0666*/); |
|
|
|
var buffer = new Buffer(4048); |
|
|
|
var buffers = []; |
|
|
|
var nread = 0; |
|
|
|
var lastRead = 0; |
|
|
|
|
|
|
|
var size; |
|
|
|
var threw = true; |
|
|
|
try { |
|
|
|
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); |
|
|
|
size = fs.fstatSync(fd).size; |
|
|
|
threw = false; |
|
|
|
} finally { |
|
|
|
if (threw) fs.closeSync(fd); |
|
|
|
} |
|
|
|
|
|
|
|
if (size === 0) { |
|
|
|
fs.closeSync(fd); |
|
|
|
return encoding ? '' : new Buffer(0); |
|
|
|
} |
|
|
|
|
|
|
|
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 if (buffers.length) { |
|
|
|
// buffers has exactly 1 (possibly zero length) buffer, so this should
|
|
|
|
// be a shortcut
|
|
|
|
buffer = buffers[0].slice(0, buffers[0]._bytesRead); |
|
|
|
} else { |
|
|
|
buffer = new Buffer(0); |
|
|
|
var buffer = new Buffer(size); |
|
|
|
var pos = 0; |
|
|
|
|
|
|
|
while (pos < size) { |
|
|
|
var threw = true; |
|
|
|
try { |
|
|
|
var bytesRead = fs.readSync(fd, buffer, pos, size - pos, pos); |
|
|
|
threw = false; |
|
|
|
} finally { |
|
|
|
if (threw) fs.closeSync(fd); |
|
|
|
} |
|
|
|
|
|
|
|
pos += bytesRead; |
|
|
|
} |
|
|
|
|
|
|
|
fs.closeSync(fd); |
|
|
|
|
|
|
|
if (encoding) buffer = buffer.toString(encoding); |
|
|
|
return buffer; |
|
|
|
}; |
|
|
|