fs: add autoClose=true option to fs.createReadStream
This commit is contained in:
parent
9f4c0988c3
commit
dcaebec208
@ -634,13 +634,20 @@ Returns a new ReadStream object (See `Readable Stream`).
|
||||
encoding: null,
|
||||
fd: null,
|
||||
mode: 0666,
|
||||
bufferSize: 64 * 1024
|
||||
bufferSize: 64 * 1024,
|
||||
autoClose: true
|
||||
}
|
||||
|
||||
`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
|
||||
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:
|
||||
|
||||
fs.createReadStream('sample.txt', {start: 90, end: 99});
|
||||
|
13
lib/fs.js
13
lib/fs.js
@ -1412,6 +1412,7 @@ function ReadStream(path, options) {
|
||||
|
||||
this.start = options.hasOwnProperty('start') ? options.start : undefined;
|
||||
this.end = options.hasOwnProperty('start') ? options.end : undefined;
|
||||
this.autoClose = options.hasOwnProperty('autoClose') ? options.autoClose : true;
|
||||
this.pos = undefined;
|
||||
|
||||
if (this.start !== undefined) {
|
||||
@ -1435,7 +1436,9 @@ function ReadStream(path, options) {
|
||||
this.open();
|
||||
|
||||
this.on('end', function() {
|
||||
this.destroy();
|
||||
if (this.autoClose) {
|
||||
this.destroy();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -1445,7 +1448,9 @@ ReadStream.prototype.open = function() {
|
||||
var self = this;
|
||||
fs.open(this.path, this.flags, this.mode, function(er, fd) {
|
||||
if (er) {
|
||||
self.destroy();
|
||||
if (this.autoClose) {
|
||||
self.destroy();
|
||||
}
|
||||
self.emit('error', er);
|
||||
return;
|
||||
}
|
||||
@ -1499,7 +1504,9 @@ ReadStream.prototype._read = function(n, cb) {
|
||||
|
||||
function onread(er, bytesRead) {
|
||||
if (er) {
|
||||
self.destroy();
|
||||
if (self.autoClose) {
|
||||
self.destroy();
|
||||
}
|
||||
return cb(er);
|
||||
}
|
||||
|
||||
|
@ -151,3 +151,41 @@ stream.on('end', function() {
|
||||
var pauseRes = fs.createReadStream(rangeFile);
|
||||
pauseRes.pause();
|
||||
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…
x
Reference in New Issue
Block a user