Browse Source

fs: Fix default params for fs.write(Sync)

Add support for fs.write(fd, buffer, cb) and fs.write(fd, buffer, offset, cb)
as documented at
https://nodejs.org/api/fs.html#fs_fs_write_fd_data_position_encoding_callback
and equivalently for fs.writeSync

Update docs and code comments to reflect the implementation.

PR-URL: https://github.com/nodejs/node/pull/7856
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Brian White <mscdex@mscdex.net>
Reviewed-By: Yorkie Liu <yorkiefixer@gmail.com>
Reviewed-By: Gibson Fahnestock <gibfahn@gmail.com>
v6
Andreas Lind 9 years ago
committed by Sam Roberts
parent
commit
0b5191f15d
  1. 20
      doc/api/fs.md
  2. 20
      lib/fs.js
  3. 120
      test/parallel/test-fs-write-buffer.js
  4. 63
      test/parallel/test-fs-write-sync.js

20
doc/api/fs.md

@ -1812,13 +1812,13 @@ _Note: [`fs.watch()`][] is more efficient than `fs.watchFile` and
`fs.unwatchFile`. `fs.watch` should be used instead of `fs.watchFile` and `fs.unwatchFile`. `fs.watch` should be used instead of `fs.watchFile` and
`fs.unwatchFile` when possible._ `fs.unwatchFile` when possible._
## fs.write(fd, buffer, offset, length[, position], callback) ## fs.write(fd, buffer[, offset[, length[, position]]], callback)
<!-- YAML <!-- YAML
added: v0.0.2 added: v0.0.2
--> -->
* `fd` {Integer} * `fd` {Integer}
* `buffer` {String | Buffer} * `buffer` {Buffer}
* `offset` {Integer} * `offset` {Integer}
* `length` {Integer} * `length` {Integer}
* `position` {Integer} * `position` {Integer}
@ -1843,19 +1843,19 @@ On Linux, positional writes don't work when the file is opened in append mode.
The kernel ignores the position argument and always appends the data to The kernel ignores the position argument and always appends the data to
the end of the file. the end of the file.
## fs.write(fd, data[, position[, encoding]], callback) ## fs.write(fd, string[, position[, encoding]], callback)
<!-- YAML <!-- YAML
added: v0.11.5 added: v0.11.5
--> -->
* `fd` {Integer} * `fd` {Integer}
* `data` {String | Buffer} * `string` {String}
* `position` {Integer} * `position` {Integer}
* `encoding` {String} * `encoding` {String}
* `callback` {Function} * `callback` {Function}
Write `data` to the file specified by `fd`. If `data` is not a Buffer instance Write `string` to the file specified by `fd`. If `string` is not a string, then
then the value will be coerced to a string. the value will be coerced to one.
`position` refers to the offset from the beginning of the file where this data `position` refers to the offset from the beginning of the file where this data
should be written. If `typeof position !== 'number'` the data will be written at should be written. If `typeof position !== 'number'` the data will be written at
@ -1936,24 +1936,24 @@ added: v0.1.29
The synchronous version of [`fs.writeFile()`][]. Returns `undefined`. The synchronous version of [`fs.writeFile()`][]. Returns `undefined`.
## fs.writeSync(fd, buffer, offset, length[, position]) ## fs.writeSync(fd, buffer[, offset[, length[, position]]])
<!-- YAML <!-- YAML
added: v0.1.21 added: v0.1.21
--> -->
* `fd` {Integer} * `fd` {Integer}
* `buffer` {String | Buffer} * `buffer` {Buffer}
* `offset` {Integer} * `offset` {Integer}
* `length` {Integer} * `length` {Integer}
* `position` {Integer} * `position` {Integer}
## fs.writeSync(fd, data[, position[, encoding]]) ## fs.writeSync(fd, string[, position[, encoding]])
<!-- YAML <!-- YAML
added: v0.11.5 added: v0.11.5
--> -->
* `fd` {Integer} * `fd` {Integer}
* `data` {String | Buffer} * `string` {String}
* `position` {Integer} * `position` {Integer}
* `encoding` {String} * `encoding` {String}

20
lib/fs.js

@ -662,7 +662,7 @@ fs.readSync = function(fd, buffer, offset, length, position) {
}; };
// usage: // usage:
// fs.write(fd, buffer, offset, length[, position], callback); // fs.write(fd, buffer[, offset[, length[, position]]], callback);
// OR // OR
// fs.write(fd, string[, position[, encoding]], callback); // fs.write(fd, string[, position[, encoding]], callback);
fs.write = function(fd, buffer, offset, length, position, callback) { fs.write = function(fd, buffer, offset, length, position, callback) {
@ -675,12 +675,16 @@ fs.write = function(fd, buffer, offset, length, position, callback) {
req.oncomplete = wrapper; req.oncomplete = wrapper;
if (buffer instanceof Buffer) { if (buffer instanceof Buffer) {
// if no position is passed then assume null callback = maybeCallback(callback || position || length || offset);
if (typeof position === 'function') { if (typeof offset !== 'number') {
callback = position; offset = 0;
}
if (typeof length !== 'number') {
length = buffer.length - offset;
}
if (typeof position !== 'number') {
position = null; position = null;
} }
callback = maybeCallback(callback);
return binding.writeBuffer(fd, buffer, offset, length, position, req); return binding.writeBuffer(fd, buffer, offset, length, position, req);
} }
@ -700,13 +704,17 @@ fs.write = function(fd, buffer, offset, length, position, callback) {
}; };
// usage: // usage:
// fs.writeSync(fd, buffer, offset, length[, position]); // fs.writeSync(fd, buffer[, offset[, length[, position]]]);
// OR // OR
// fs.writeSync(fd, string[, position[, encoding]]); // fs.writeSync(fd, string[, position[, encoding]]);
fs.writeSync = function(fd, buffer, offset, length, position) { fs.writeSync = function(fd, buffer, offset, length, position) {
if (buffer instanceof Buffer) { if (buffer instanceof Buffer) {
if (position === undefined) if (position === undefined)
position = null; position = null;
if (typeof offset !== 'number')
offset = 0;
if (typeof length !== 'number')
length = buffer.length - offset;
return binding.writeBuffer(fd, buffer, offset, length, position); return binding.writeBuffer(fd, buffer, offset, length, position);
} }
if (typeof buffer !== 'string') if (typeof buffer !== 'string')

120
test/parallel/test-fs-write-buffer.js

@ -2,29 +2,107 @@
const common = require('../common'); const common = require('../common');
const assert = require('assert'); const assert = require('assert');
const path = require('path'); const path = require('path');
const Buffer = require('buffer').Buffer;
const fs = require('fs'); const fs = require('fs');
const filename = path.join(common.tmpDir, 'write.txt');
const expected = Buffer.from('hello'); const expected = Buffer.from('hello');
common.refreshTmpDir(); common.refreshTmpDir();
fs.open(filename, 'w', 0o644, common.mustCall(function(err, fd) { // fs.write with all parameters provided:
if (err) throw err; {
const filename = path.join(common.tmpDir, 'write1.txt');
fs.write(fd, fs.open(filename, 'w', 0o644, common.mustCall(function(err, fd) {
expected, assert.ifError(err);
0,
expected.length, const cb = common.mustCall(function(err, written) {
null, assert.ifError(err);
common.mustCall(function(err, written) {
if (err) throw err; assert.strictEqual(expected.length, written);
fs.closeSync(fd);
assert.equal(expected.length, written);
fs.closeSync(fd); var found = fs.readFileSync(filename, 'utf8');
assert.deepStrictEqual(expected.toString(), found);
var found = fs.readFileSync(filename, 'utf8'); });
assert.deepStrictEqual(expected.toString(), found);
fs.unlinkSync(filename); fs.write(fd, expected, 0, expected.length, null, cb);
})); }));
})); }
// fs.write with a buffer, without the length parameter:
{
const filename = path.join(common.tmpDir, 'write2.txt');
fs.open(filename, 'w', 0o644, common.mustCall(function(err, fd) {
assert.ifError(err);
const cb = common.mustCall(function(err, written) {
assert.ifError(err);
assert.strictEqual(2, written);
fs.closeSync(fd);
const found = fs.readFileSync(filename, 'utf8');
assert.deepStrictEqual('lo', found);
});
fs.write(fd, Buffer.from('hello'), 3, cb);
}));
}
// fs.write with a buffer, without the offset and length parameters:
{
const filename = path.join(common.tmpDir, 'write3.txt');
fs.open(filename, 'w', 0o644, common.mustCall(function(err, fd) {
assert.ifError(err);
const cb = common.mustCall(function(err, written) {
assert.ifError(err);
assert.strictEqual(expected.length, written);
fs.closeSync(fd);
const found = fs.readFileSync(filename, 'utf8');
assert.deepStrictEqual(expected.toString(), found);
});
fs.write(fd, expected, cb);
}));
}
// fs.write with the offset passed as undefined followed by the callback:
{
const filename = path.join(common.tmpDir, 'write4.txt');
fs.open(filename, 'w', 0o644, common.mustCall(function(err, fd) {
assert.ifError(err);
const cb = common.mustCall(function(err, written) {
assert.ifError(err);
assert.strictEqual(expected.length, written);
fs.closeSync(fd);
const found = fs.readFileSync(filename, 'utf8');
assert.deepStrictEqual(expected.toString(), found);
});
fs.write(fd, expected, undefined, cb);
}));
}
// fs.write with offset and length passed as undefined followed by the callback:
{
const filename = path.join(common.tmpDir, 'write5.txt');
fs.open(filename, 'w', 0o644, common.mustCall(function(err, fd) {
assert.ifError(err);
const cb = common.mustCall(function(err, written) {
assert.ifError(err);
assert.strictEqual(expected.length, written);
fs.closeSync(fd);
const found = fs.readFileSync(filename, 'utf8');
assert.deepStrictEqual(expected.toString(), found);
});
fs.write(fd, expected, undefined, undefined, cb);
}));
}

63
test/parallel/test-fs-write-sync.js

@ -1,23 +1,56 @@
'use strict'; 'use strict';
var common = require('../common'); const common = require('../common');
var assert = require('assert'); const assert = require('assert');
var path = require('path'); const path = require('path');
var fs = require('fs'); const fs = require('fs');
var fn = path.join(common.tmpDir, 'write.txt'); const filename = path.join(common.tmpDir, 'write.txt');
common.refreshTmpDir(); common.refreshTmpDir();
var foo = 'foo'; // fs.writeSync with all parameters provided:
var fd = fs.openSync(fn, 'w'); {
const fd = fs.openSync(filename, 'w');
var written = fs.writeSync(fd, ''); let written = fs.writeSync(fd, '');
assert.strictEqual(0, written); assert.strictEqual(0, written);
fs.writeSync(fd, foo); fs.writeSync(fd, 'foo');
var bar = 'bár'; written = fs.writeSync(fd, Buffer.from('bár'), 0, Buffer.byteLength('bár'));
written = fs.writeSync(fd, Buffer.from(bar), 0, Buffer.byteLength(bar)); assert.ok(written > 3);
assert.ok(written > 3); fs.closeSync(fd);
fs.closeSync(fd);
assert.equal(fs.readFileSync(fn), 'foobár'); assert.strictEqual(fs.readFileSync(filename, 'utf-8'), 'foobár');
}
// fs.writeSync with a buffer, without the length parameter:
{
const fd = fs.openSync(filename, 'w');
let written = fs.writeSync(fd, '');
assert.strictEqual(0, written);
fs.writeSync(fd, 'foo');
written = fs.writeSync(fd, Buffer.from('bár'), 0);
assert.ok(written > 3);
fs.closeSync(fd);
assert.strictEqual(fs.readFileSync(filename, 'utf-8'), 'foobár');
}
// fs.writeSync with a buffer, without the offset and length parameters:
{
const fd = fs.openSync(filename, 'w');
let written = fs.writeSync(fd, '');
assert.strictEqual(0, written);
fs.writeSync(fd, 'foo');
written = fs.writeSync(fd, Buffer.from('bár'));
assert.ok(written > 3);
fs.closeSync(fd);
assert.strictEqual(fs.readFileSync(filename, 'utf-8'), 'foobár');
}

Loading…
Cancel
Save