diff --git a/doc/api/fs.markdown b/doc/api/fs.markdown index b9eca2f914..bb90cc8d2e 100644 --- a/doc/api/fs.markdown +++ b/doc/api/fs.markdown @@ -795,7 +795,7 @@ on Unix systems, it never was. Returns a new ReadStream object (See `Readable Stream`). -`options` is an object with the following defaults: +`options` is an object or string with the following defaults: { flags: 'r', encoding: null, @@ -821,6 +821,7 @@ An example to read the last 10 bytes of a file which is 100 bytes long: fs.createReadStream('sample.txt', {start: 90, end: 99}); +If `options` is a string, then it specifies the encoding. ## Class: fs.ReadStream @@ -837,7 +838,7 @@ Emitted when the ReadStream's file is opened. Returns a new WriteStream object (See `Writable Stream`). -`options` is an object with the following defaults: +`options` is an object or string with the following defaults: { flags: 'w', encoding: null, @@ -854,6 +855,7 @@ Like `ReadStream` above, if `fd` is specified, `WriteStream` will ignore the `path` argument and will use the specified file descriptor. This means that no `open` event will be emitted. +If `options` is a string, then it specifies the encoding. ## Class: fs.WriteStream diff --git a/lib/fs.js b/lib/fs.js index e86a7d0705..72251d0b75 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1617,8 +1617,15 @@ function ReadStream(path, options) { if (!(this instanceof ReadStream)) return new ReadStream(path, options); + if (options === undefined) + options = {}; + else if (typeof options === 'string') + options = { encoding: options }; + else if (options === null || typeof options !== 'object') + throw new TypeError('options must be a string or an object'); + // a little bit bigger buffer and water marks by default - options = Object.create(options || {}); + options = Object.create(options); if (options.highWaterMark === undefined) options.highWaterMark = 64 * 1024; @@ -1783,7 +1790,14 @@ function WriteStream(path, options) { if (!(this instanceof WriteStream)) return new WriteStream(path, options); - options = options || {}; + if (options === undefined) + options = {}; + else if (typeof options === 'string') + options = { encoding: options }; + else if (options === null || typeof options !== 'object') + throw new TypeError('options must be a string or an object'); + + options = Object.create(options); Writable.call(this, options); diff --git a/test/parallel/test-fs-read-stream-encoding.js b/test/parallel/test-fs-read-stream-encoding.js new file mode 100644 index 0000000000..68699136ea --- /dev/null +++ b/test/parallel/test-fs-read-stream-encoding.js @@ -0,0 +1,17 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); +const stream = require('stream'); +const encoding = 'base64'; + +const example = path.join(common.fixturesDir, 'x.txt'); +const assertStream = new stream.Writable({ + write: function(chunk, enc, next) { + const expected = new Buffer('xyz'); + assert(chunk.equals(expected)); + } +}); +assertStream.setDefaultEncoding(encoding); +fs.createReadStream(example, encoding).pipe(assertStream); diff --git a/test/parallel/test-fs-read-stream-throw-type-error.js b/test/parallel/test-fs-read-stream-throw-type-error.js new file mode 100644 index 0000000000..b3e63816ce --- /dev/null +++ b/test/parallel/test-fs-read-stream-throw-type-error.js @@ -0,0 +1,33 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +const example = path.join(common.fixturesDir, 'x.txt'); + +assert.doesNotThrow(function() { + fs.createReadStream(example, undefined); +}); +assert.doesNotThrow(function() { + fs.createReadStream(example, 'utf8'); +}); +assert.doesNotThrow(function() { + fs.createReadStream(example, {encoding: 'utf8'}); +}); + +assert.throws(function() { + fs.createReadStream(example, null); +}, /options must be a string or an object/); +assert.throws(function() { + fs.createReadStream(example, 123); +}, /options must be a string or an object/); +assert.throws(function() { + fs.createReadStream(example, 0); +}, /options must be a string or an object/); +assert.throws(function() { + fs.createReadStream(example, true); +}, /options must be a string or an object/); +assert.throws(function() { + fs.createReadStream(example, false); +}, /options must be a string or an object/); diff --git a/test/parallel/test-fs-write-stream-throw-type-error.js b/test/parallel/test-fs-write-stream-throw-type-error.js new file mode 100644 index 0000000000..8568dd4eea --- /dev/null +++ b/test/parallel/test-fs-write-stream-throw-type-error.js @@ -0,0 +1,33 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +const example = path.join(common.tmpDir, 'dummy'); + +assert.doesNotThrow(function() { + fs.createWriteStream(example, undefined); +}); +assert.doesNotThrow(function() { + fs.createWriteStream(example, 'utf8'); +}); +assert.doesNotThrow(function() { + fs.createWriteStream(example, {encoding: 'utf8'}); +}); + +assert.throws(function() { + fs.createWriteStream(example, null); +}, /options must be a string or an object/); +assert.throws(function() { + fs.createWriteStream(example, 123); +}, /options must be a string or an object/); +assert.throws(function() { + fs.createWriteStream(example, 0); +}, /options must be a string or an object/); +assert.throws(function() { + fs.createWriteStream(example, true); +}, /options must be a string or an object/); +assert.throws(function() { + fs.createWriteStream(example, false); +}, /options must be a string or an object/);