Permalink
Please
sign in to comment.
Browse files
fs: add fs.writev() which exposes syscall writev()
fs with writev allow many buffers to be pushed to underlying OS APIs in one batch, so this should improve write speed to files. Refs: #2298 PR-URL: #25925 Fixes: #2298 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
- Loading branch information...
Showing
with
294 additions
and 5 deletions.
- +47 −0 doc/api/fs.md
- +64 −1 lib/fs.js
- +87 −0 test/parallel/test-fs-writev-sync.js
- +92 −0 test/parallel/test-fs-writev.js
- +4 −4 tools/doc/type-parser.js
| @@ -0,0 +1,87 @@ | |||
| 'use strict'; | |||
|
|
|||
| const common = require('../common'); | |||
| const assert = require('assert'); | |||
| const path = require('path'); | |||
| const fs = require('fs'); | |||
| const tmpdir = require('../common/tmpdir'); | |||
|
|
|||
| tmpdir.refresh(); | |||
|
|
|||
| const expected = 'ümlaut. Лорем 運務ホソモ指及 आपको करने विकास 紙読決多密所 أضف'; | |||
|
|
|||
| const getFileName = (i) => path.join(tmpdir.path, `writev_sync_${i}.txt`); | |||
|
|
|||
| /** | |||
| * Testing with a array of buffers input | |||
| */ | |||
|
|
|||
| // fs.writevSync with array of buffers with all parameters | |||
| { | |||
| const filename = getFileName(1); | |||
| const fd = fs.openSync(filename, 'w'); | |||
|
|
|||
| const buffer = Buffer.from(expected); | |||
| const bufferArr = [buffer, buffer]; | |||
| const expectedLength = bufferArr.length * buffer.byteLength; | |||
|
|
|||
| let written = fs.writevSync(fd, [Buffer.from('')], null); | |||
| assert.deepStrictEqual(written, 0); | |||
|
|
|||
| written = fs.writevSync(fd, bufferArr, null); | |||
| assert.deepStrictEqual(written, expectedLength); | |||
|
|
|||
| fs.closeSync(fd); | |||
|
|
|||
| assert(Buffer.concat(bufferArr).equals(fs.readFileSync(filename))); | |||
| } | |||
|
|
|||
| // fs.writevSync with array of buffers without position | |||
| { | |||
| const filename = getFileName(2); | |||
| const fd = fs.openSync(filename, 'w'); | |||
|
|
|||
| const buffer = Buffer.from(expected); | |||
| const bufferArr = [buffer, buffer, buffer]; | |||
| const expectedLength = bufferArr.length * buffer.byteLength; | |||
|
|
|||
| let written = fs.writevSync(fd, [Buffer.from('')]); | |||
| assert.deepStrictEqual(written, 0); | |||
|
|
|||
| written = fs.writevSync(fd, bufferArr); | |||
| assert.deepStrictEqual(written, expectedLength); | |||
|
|
|||
| fs.closeSync(fd); | |||
|
|
|||
| assert(Buffer.concat(bufferArr).equals(fs.readFileSync(filename))); | |||
| } | |||
|
|
|||
| /** | |||
| * Testing with wrong input types | |||
| */ | |||
| { | |||
| const filename = getFileName(3); | |||
| const fd = fs.openSync(filename, 'w'); | |||
|
|
|||
| [false, 'test', {}, [{}], ['sdf'], null, undefined].forEach((i) => { | |||
| common.expectsError( | |||
| () => fs.writevSync(fd, i, null), { | |||
| code: 'ERR_INVALID_ARG_TYPE', | |||
| type: TypeError | |||
| } | |||
| ); | |||
| }); | |||
|
|
|||
| fs.closeSync(fd); | |||
| } | |||
|
|
|||
| // fs.writevSync with wrong fd types | |||
| [false, 'test', {}, [{}], null, undefined].forEach((i) => { | |||
| common.expectsError( | |||
| () => fs.writevSync(i), | |||
| { | |||
| code: 'ERR_INVALID_ARG_TYPE', | |||
| type: TypeError | |||
| } | |||
| ); | |||
| }); | |||
| @@ -0,0 +1,92 @@ | |||
| 'use strict'; | |||
|
|
|||
| const common = require('../common'); | |||
| const assert = require('assert'); | |||
| const path = require('path'); | |||
| const fs = require('fs'); | |||
| const tmpdir = require('../common/tmpdir'); | |||
|
|
|||
| tmpdir.refresh(); | |||
|
|
|||
| const expected = 'ümlaut. Лорем 運務ホソモ指及 आपको करने विकास 紙読決多密所 أضف'; | |||
|
|
|||
| const getFileName = (i) => path.join(tmpdir.path, `writev_${i}.txt`); | |||
|
|
|||
| /** | |||
| * Testing with a array of buffers input | |||
| */ | |||
|
|
|||
| // fs.writev with array of buffers with all parameters | |||
| { | |||
| const filename = getFileName(1); | |||
| const fd = fs.openSync(filename, 'w'); | |||
|
|
|||
| const buffer = Buffer.from(expected); | |||
| const bufferArr = [buffer, buffer]; | |||
|
|
|||
| const done = common.mustCall((err, written, buffers) => { | |||
| assert.ifError(err); | |||
|
|
|||
| assert.deepStrictEqual(bufferArr, buffers); | |||
| const expectedLength = bufferArr.length * buffer.byteLength; | |||
| assert.deepStrictEqual(written, expectedLength); | |||
| fs.closeSync(fd); | |||
|
|
|||
| assert(Buffer.concat(bufferArr).equals(fs.readFileSync(filename))); | |||
| }); | |||
|
|
|||
| fs.writev(fd, bufferArr, null, done); | |||
| } | |||
|
|
|||
| // fs.writev with array of buffers without position | |||
| { | |||
| const filename = getFileName(2); | |||
| const fd = fs.openSync(filename, 'w'); | |||
|
|
|||
| const buffer = Buffer.from(expected); | |||
| const bufferArr = [buffer, buffer]; | |||
|
|
|||
| const done = common.mustCall((err, written, buffers) => { | |||
| assert.ifError(err); | |||
|
|
|||
| assert.deepStrictEqual(bufferArr, buffers); | |||
|
|
|||
| const expectedLength = bufferArr.length * buffer.byteLength; | |||
| assert.deepStrictEqual(written, expectedLength); | |||
| fs.closeSync(fd); | |||
|
|
|||
| assert(Buffer.concat(bufferArr).equals(fs.readFileSync(filename))); | |||
| }); | |||
|
|
|||
| fs.writev(fd, bufferArr, done); | |||
| } | |||
|
|
|||
| /** | |||
| * Testing with wrong input types | |||
| */ | |||
| { | |||
| const filename = getFileName(3); | |||
| const fd = fs.openSync(filename, 'w'); | |||
|
|
|||
| [false, 'test', {}, [{}], ['sdf'], null, undefined].forEach((i) => { | |||
| common.expectsError( | |||
| () => fs.writev(fd, i, null, common.mustNotCall()), { | |||
| code: 'ERR_INVALID_ARG_TYPE', | |||
| type: TypeError | |||
| } | |||
| ); | |||
| }); | |||
|
|
|||
| fs.closeSync(fd); | |||
| } | |||
|
|
|||
| // fs.writev with wrong fd types | |||
| [false, 'test', {}, [{}], null, undefined].forEach((i) => { | |||
| common.expectsError( | |||
| () => fs.writev(i, common.mustNotCall()), | |||
| { | |||
| code: 'ERR_INVALID_ARG_TYPE', | |||
| type: TypeError | |||
| } | |||
| ); | |||
| }); | |||
0 comments on commit
bb19d82