Support for reading byte ranges from files using fs.createReadStream.
This commit is contained in:
parent
56f200af5d
commit
f5f7cb9264
@ -1583,6 +1583,14 @@ Returns a new ReadStream object (See `Readable Stream`).
|
|||||||
, 'bufferSize': 4 * 1024
|
, 'bufferSize': 4 * 1024
|
||||||
}
|
}
|
||||||
|
|
||||||
|
`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. When used, both the limits must be specified always.
|
||||||
|
|
||||||
|
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.WriteStream
|
## fs.WriteStream
|
||||||
|
|
||||||
|
25
lib/fs.js
25
lib/fs.js
@ -615,6 +615,16 @@ var ReadStream = fs.ReadStream = function(path, options) {
|
|||||||
this[key] = options[key];
|
this[key] = options[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.start || this.end) {
|
||||||
|
if(this.start === undefined || this.end === undefined) {
|
||||||
|
self.emit('error', new Error('Both start and end are needed for range streaming.'));
|
||||||
|
} else if(this.start > this.end) {
|
||||||
|
self.emit('error', new Error('start must be <= end'));
|
||||||
|
} else {
|
||||||
|
this.firstRead = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (this.fd !== null) {
|
if (this.fd !== null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -653,6 +663,11 @@ ReadStream.prototype._read = function () {
|
|||||||
allocNewPool();
|
allocNewPool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.start && this.firstRead) {
|
||||||
|
this.pos = this.start;
|
||||||
|
this.firstRead = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Grab another reference to the pool in the case that while we're in the
|
// Grab another reference to the pool in the case that while we're in the
|
||||||
// thread pool another read() finishes up the pool, and allocates a new
|
// thread pool another read() finishes up the pool, and allocates a new
|
||||||
// one.
|
// one.
|
||||||
@ -660,6 +675,10 @@ ReadStream.prototype._read = function () {
|
|||||||
var toRead = Math.min(pool.length - pool.used, this.bufferSize);
|
var toRead = Math.min(pool.length - pool.used, this.bufferSize);
|
||||||
var start = pool.used;
|
var start = pool.used;
|
||||||
|
|
||||||
|
if(this.pos) {
|
||||||
|
toRead = Math.min(this.end - this.pos + 1, toRead);
|
||||||
|
}
|
||||||
|
|
||||||
function afterRead (err, bytesRead) {
|
function afterRead (err, bytesRead) {
|
||||||
if (err) {
|
if (err) {
|
||||||
self.emit('error', err);
|
self.emit('error', err);
|
||||||
@ -692,7 +711,11 @@ ReadStream.prototype._read = function () {
|
|||||||
self._read();
|
self._read();
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.read(self.fd, pool, pool.used, toRead, undefined, afterRead);
|
fs.read(self.fd, pool, pool.used, toRead, this.pos, afterRead);
|
||||||
|
|
||||||
|
if(self.pos) {
|
||||||
|
self.pos += toRead;
|
||||||
|
}
|
||||||
pool.used += toRead;
|
pool.used += toRead;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ Buffer = require('buffer').Buffer;
|
|||||||
path = require('path');
|
path = require('path');
|
||||||
fs = require('fs');
|
fs = require('fs');
|
||||||
fn = path.join(common.fixturesDir, 'elipses.txt');
|
fn = path.join(common.fixturesDir, 'elipses.txt');
|
||||||
|
rangeFile = path.join(common.fixturesDir, 'x.txt');
|
||||||
|
|
||||||
callbacks = { open: 0, end: 0, close: 0, destroy: 0 };
|
callbacks = { open: 0, end: 0, close: 0, destroy: 0 };
|
||||||
|
|
||||||
@ -86,3 +87,12 @@ process.addListener('exit', function() {
|
|||||||
assert.equal(30000, file.length);
|
assert.equal(30000, file.length);
|
||||||
assert.equal(10000, file3.length);
|
assert.equal(10000, file3.length);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var file4 = fs.createReadStream(rangeFile, {start: 1, end: 2});
|
||||||
|
var contentRead = '';
|
||||||
|
file4.addListener('data', function(data) {
|
||||||
|
contentRead += data.toString('utf-8');
|
||||||
|
});
|
||||||
|
file4.addListener('end', function(data) {
|
||||||
|
assert.equal(contentRead, 'yz');
|
||||||
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user