Browse Source

Support for reading byte ranges from files using fs.createReadStream.

v0.7.4-release
Chandra Sekar S 14 years ago
committed by Ryan Dahl
parent
commit
f5f7cb9264
  1. 8
      doc/api.markdown
  2. 25
      lib/fs.js
  3. 10
      test/simple/test-fs-read-stream.js

8
doc/api.markdown

@ -1583,6 +1583,14 @@ Returns a new ReadStream object (See `Readable Stream`).
, '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

25
lib/fs.js

@ -615,6 +615,16 @@ var ReadStream = fs.ReadStream = function(path, options) {
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) {
return;
}
@ -653,6 +663,11 @@ ReadStream.prototype._read = function () {
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
// thread pool another read() finishes up the pool, and allocates a new
// one.
@ -660,6 +675,10 @@ ReadStream.prototype._read = function () {
var toRead = Math.min(pool.length - pool.used, this.bufferSize);
var start = pool.used;
if(this.pos) {
toRead = Math.min(this.end - this.pos + 1, toRead);
}
function afterRead (err, bytesRead) {
if (err) {
self.emit('error', err);
@ -692,7 +711,11 @@ ReadStream.prototype._read = function () {
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;
};

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

@ -9,6 +9,7 @@ Buffer = require('buffer').Buffer;
path = require('path');
fs = require('fs');
fn = path.join(common.fixturesDir, 'elipses.txt');
rangeFile = path.join(common.fixturesDir, 'x.txt');
callbacks = { open: 0, end: 0, close: 0, destroy: 0 };
@ -86,3 +87,12 @@ process.addListener('exit', function() {
assert.equal(30000, file.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…
Cancel
Save