Browse Source

fs: add autoClose=true option to fs.createReadStream

v0.9.4-release
Farid Neshat 12 years ago
committed by Ben Noordhuis
parent
commit
dcaebec208
  1. 9
      doc/api/fs.markdown
  2. 13
      lib/fs.js
  3. 38
      test/simple/test-fs-read-stream.js

9
doc/api/fs.markdown

@ -634,13 +634,20 @@ Returns a new ReadStream object (See `Readable Stream`).
encoding: null, encoding: null,
fd: null, fd: null,
mode: 0666, mode: 0666,
bufferSize: 64 * 1024 bufferSize: 64 * 1024,
autoClose: true
} }
`options` can include `start` and `end` values to read a range of bytes from `options` can include `start` and `end` values to read a range of bytes from
the file instead of the entire file. Both `start` and `end` are inclusive and the file instead of the entire file. Both `start` and `end` are inclusive and
start at 0. The `encoding` can be `'utf8'`, `'ascii'`, or `'base64'`. start at 0. The `encoding` can be `'utf8'`, `'ascii'`, or `'base64'`.
If `autoClose` is false, then the file descriptor won't be closed, even if
there's an error. It is your responsiblity to close it and make sure
there's no file descriptor leak. If `autoClose` is set to true (default
behavior), on `error` or `end` the file descriptor will be closed
automatically.
An example to read the last 10 bytes of a file which is 100 bytes long: An example to read the last 10 bytes of a file which is 100 bytes long:
fs.createReadStream('sample.txt', {start: 90, end: 99}); fs.createReadStream('sample.txt', {start: 90, end: 99});

13
lib/fs.js

@ -1412,6 +1412,7 @@ function ReadStream(path, options) {
this.start = options.hasOwnProperty('start') ? options.start : undefined; this.start = options.hasOwnProperty('start') ? options.start : undefined;
this.end = options.hasOwnProperty('start') ? options.end : undefined; this.end = options.hasOwnProperty('start') ? options.end : undefined;
this.autoClose = options.hasOwnProperty('autoClose') ? options.autoClose : true;
this.pos = undefined; this.pos = undefined;
if (this.start !== undefined) { if (this.start !== undefined) {
@ -1435,7 +1436,9 @@ function ReadStream(path, options) {
this.open(); this.open();
this.on('end', function() { this.on('end', function() {
this.destroy(); if (this.autoClose) {
this.destroy();
}
}); });
} }
@ -1445,7 +1448,9 @@ ReadStream.prototype.open = function() {
var self = this; var self = this;
fs.open(this.path, this.flags, this.mode, function(er, fd) { fs.open(this.path, this.flags, this.mode, function(er, fd) {
if (er) { if (er) {
self.destroy(); if (this.autoClose) {
self.destroy();
}
self.emit('error', er); self.emit('error', er);
return; return;
} }
@ -1499,7 +1504,9 @@ ReadStream.prototype._read = function(n, cb) {
function onread(er, bytesRead) { function onread(er, bytesRead) {
if (er) { if (er) {
self.destroy(); if (self.autoClose) {
self.destroy();
}
return cb(er); return cb(er);
} }

38
test/simple/test-fs-read-stream.js

@ -151,3 +151,41 @@ stream.on('end', function() {
var pauseRes = fs.createReadStream(rangeFile); var pauseRes = fs.createReadStream(rangeFile);
pauseRes.pause(); pauseRes.pause();
pauseRes.resume(); pauseRes.resume();
var file7 = fs.createReadStream(rangeFile, {autoClose: false });
file7.on('data', function() {});
file7.on('end', function() {
process.nextTick(function() {
assert(!file7.closed);
assert(!file7.destroyed);
file7Next();
});
});
function file7Next(){
// This will tell us if the fd is usable again or not.
file7 = fs.createReadStream(null, {fd: file7.fd, start: 0 });
file7.data = '';
file7.on('data', function(data) {
file7.data += data;
});
file7.on('end', function(err) {
assert.equal(file7.data, 'xyz\n');
process.nextTick(function() {
assert(file7.closed);
assert(file7.destroyed);
});
});
}
// Just to make sure autoClose won't close the stream because of error.
var file8 = fs.createReadStream(null, {fd: 13337, autoClose: false });
file8.on('data', function() {});
file8.on('error', common.mustCall(function() {}));
file8.on('end', function() {
process.nextTick(function() {
assert(!file8.closed);
assert(!file8.destroyed);
assert(file8.fd);
});
});

Loading…
Cancel
Save