Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 81f3eb5

Browse filesBrowse files
cjihrigtargos
authored andcommitted
fs: add writev() promises version
#25925 added fs.writev() and fs.writevSync(), but did not include a Promises based equivalent. This commit adds the missing method. Refs: #25925 PR-URL: #29186 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 4356836 commit 81f3eb5
Copy full SHA for 81f3eb5

File tree

Expand file treeCollapse file tree

4 files changed

+108
-0
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

4 files changed

+108
-0
lines changed
Open diff view settings
Collapse file

‎doc/api/fs.md‎

Copy file name to clipboardExpand all lines: doc/api/fs.md
+26Lines changed: 26 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -4212,6 +4212,32 @@ If one or more `filehandle.write()` calls are made on a file handle and then a
42124212
current position till the end of the file. It doesn't always write from the
42134213
beginning of the file.
42144214

4215+
#### filehandle.writev(buffers[, position])
4216+
<!-- YAML
4217+
added: REPLACEME
4218+
-->
4219+
4220+
* `buffers` {ArrayBufferView[]}
4221+
* `position` {integer}
4222+
* Returns: {Promise}
4223+
4224+
Write an array of `ArrayBufferView`s to the file.
4225+
4226+
The `Promise` is resolved with an object containing a `bytesWritten` property
4227+
identifying the number of bytes written, and a `buffers` property containing
4228+
a reference to the `buffers` input.
4229+
4230+
`position` is the offset from the beginning of the file where this data
4231+
should be written. If `typeof position !== 'number'`, the data will be written
4232+
at the current position.
4233+
4234+
It is unsafe to call `writev()` multiple times on the same file without waiting
4235+
for the previous operation to complete.
4236+
4237+
On Linux, positional writes don't work when the file is opened in append mode.
4238+
The kernel ignores the position argument and always appends the data to
4239+
the end of the file.
4240+
42154241
### fsPromises.access(path[, mode])
42164242
<!-- YAML
42174243
added: v10.0.0
Collapse file

‎lib/internal/fs/promises.js‎

Copy file name to clipboardExpand all lines: lib/internal/fs/promises.js
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const {
2929
stringToFlags,
3030
stringToSymlinkType,
3131
toUnixTimestamp,
32+
validateBufferArray,
3233
validateOffsetLengthRead,
3334
validateOffsetLengthWrite,
3435
warnOnNonPortableTemplate
@@ -104,6 +105,10 @@ class FileHandle {
104105
return write(this, buffer, offset, length, position);
105106
}
106107

108+
writev(buffers, position) {
109+
return writev(this, buffers, position);
110+
}
111+
107112
writeFile(data, options) {
108113
return writeFile(this, data, options);
109114
}
@@ -255,6 +260,18 @@ async function write(handle, buffer, offset, length, position) {
255260
return { bytesWritten, buffer };
256261
}
257262

263+
async function writev(handle, buffers, position) {
264+
validateFileHandle(handle);
265+
validateBufferArray(buffers);
266+
267+
if (typeof position !== 'number')
268+
position = null;
269+
270+
const bytesWritten = (await binding.writeBuffers(handle.fd, buffers, position,
271+
kUsePromises)) || 0;
272+
return { bytesWritten, buffers };
273+
}
274+
258275
async function rename(oldPath, newPath) {
259276
oldPath = getValidatedPath(oldPath, 'oldPath');
260277
newPath = getValidatedPath(newPath, 'newPath');
Collapse file

‎lib/internal/fs/utils.js‎

Copy file name to clipboardExpand all lines: lib/internal/fs/utils.js
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const {
1515
hideStackFrames
1616
} = require('internal/errors');
1717
const {
18+
isArrayBufferView,
1819
isUint8Array,
1920
isDate
2021
} = require('internal/util/types');
@@ -439,6 +440,18 @@ const getValidatedPath = hideStackFrames((fileURLOrPath, propName = 'path') => {
439440
return path;
440441
});
441442

443+
const validateBufferArray = hideStackFrames((buffers, propName = 'buffers') => {
444+
if (!Array.isArray(buffers))
445+
throw new ERR_INVALID_ARG_TYPE(propName, 'ArrayBufferView[]', buffers);
446+
447+
for (let i = 0; i < buffers.length; i++) {
448+
if (!isArrayBufferView(buffers[i]))
449+
throw new ERR_INVALID_ARG_TYPE(propName, 'ArrayBufferView[]', buffers);
450+
}
451+
452+
return buffers;
453+
});
454+
442455
let nonPortableTemplateWarn = true;
443456

444457
function warnOnNonPortableTemplate(template) {
@@ -466,6 +479,7 @@ module.exports = {
466479
stringToSymlinkType,
467480
Stats,
468481
toUnixTimestamp,
482+
validateBufferArray,
469483
validateOffsetLengthRead,
470484
validateOffsetLengthWrite,
471485
validatePath,
Collapse file
+51Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
'use strict';
2+
3+
require('../common');
4+
const assert = require('assert');
5+
const path = require('path');
6+
const fs = require('fs').promises;
7+
const tmpdir = require('../common/tmpdir');
8+
const expected = 'ümlaut. Лорем 運務ホソモ指及 आपको करने विकास 紙読決多密所 أضف';
9+
let cnt = 0;
10+
11+
function getFileName() {
12+
return path.join(tmpdir.path, `writev_promises_${++cnt}.txt`);
13+
}
14+
15+
tmpdir.refresh();
16+
17+
(async () => {
18+
{
19+
const filename = getFileName();
20+
const handle = await fs.open(filename, 'w');
21+
const buffer = Buffer.from(expected);
22+
const bufferArr = [buffer, buffer];
23+
const expectedLength = bufferArr.length * buffer.byteLength;
24+
let { bytesWritten, buffers } = await handle.writev([Buffer.from('')],
25+
null);
26+
assert.deepStrictEqual(bytesWritten, 0);
27+
assert.deepStrictEqual(buffers, [Buffer.from('')]);
28+
({ bytesWritten, buffers } = await handle.writev(bufferArr, null));
29+
assert.deepStrictEqual(bytesWritten, expectedLength);
30+
assert.deepStrictEqual(buffers, bufferArr);
31+
assert(Buffer.concat(bufferArr).equals(await fs.readFile(filename)));
32+
handle.close();
33+
}
34+
35+
// fs.promises.writev() with an array of buffers without position.
36+
{
37+
const filename = getFileName();
38+
const handle = await fs.open(filename, 'w');
39+
const buffer = Buffer.from(expected);
40+
const bufferArr = [buffer, buffer, buffer];
41+
const expectedLength = bufferArr.length * buffer.byteLength;
42+
let { bytesWritten, buffers } = await handle.writev([Buffer.from('')]);
43+
assert.deepStrictEqual(bytesWritten, 0);
44+
assert.deepStrictEqual(buffers, [Buffer.from('')]);
45+
({ bytesWritten, buffers } = await handle.writev(bufferArr));
46+
assert.deepStrictEqual(bytesWritten, expectedLength);
47+
assert.deepStrictEqual(buffers, bufferArr);
48+
assert(Buffer.concat(bufferArr).equals(await fs.readFile(filename)));
49+
handle.close();
50+
}
51+
})();

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.