mirror of https://github.com/nodejs/node.git
fs: fix fs.promises.writeFile with typed arrays
Before this change, only the first part of typed arrays which have more than 1 byte per element (e.g. Uint16Array) would be written. This also removes the use of the `slice` method to avoid unnecessary copying the data. Fixes: https://github.com/nodejs/node/issues/35343 PR-URL: https://github.com/nodejs/node/pull/35376 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Zeyu Yang <himself65@outlook.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
This commit is contained in:
parent
1390574d66
commit
56e36f41aa
|
@ -10,12 +10,13 @@ const kReadFileMaxChunkSize = 2 ** 14;
|
|||
const kWriteFileMaxChunkSize = 2 ** 14;
|
||||
|
||||
const {
|
||||
Error,
|
||||
MathMax,
|
||||
MathMin,
|
||||
NumberIsSafeInteger,
|
||||
Symbol,
|
||||
Error,
|
||||
Promise,
|
||||
Symbol,
|
||||
Uint8Array,
|
||||
} = primordials;
|
||||
|
||||
const {
|
||||
|
@ -237,6 +238,8 @@ async function fsCall(fn, handle, ...args) {
|
|||
}
|
||||
|
||||
async function writeFileHandle(filehandle, data) {
|
||||
// `data` could be any kind of typed array.
|
||||
data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
||||
let remaining = data.length;
|
||||
if (remaining === 0) return;
|
||||
do {
|
||||
|
@ -244,7 +247,11 @@ async function writeFileHandle(filehandle, data) {
|
|||
await write(filehandle, data, 0,
|
||||
MathMin(kWriteFileMaxChunkSize, data.length));
|
||||
remaining -= bytesWritten;
|
||||
data = data.slice(bytesWritten);
|
||||
data = new Uint8Array(
|
||||
data.buffer,
|
||||
data.byteOffset + bytesWritten,
|
||||
data.byteLength - bytesWritten
|
||||
);
|
||||
} while (remaining > 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
const fs = require('fs');
|
||||
const fsPromises = fs.promises;
|
||||
const path = require('path');
|
||||
const tmpdir = require('../common/tmpdir');
|
||||
const assert = require('assert');
|
||||
const tmpDir = tmpdir.path;
|
||||
|
||||
tmpdir.refresh();
|
||||
|
||||
const dest = path.resolve(tmpDir, 'tmp.txt');
|
||||
// Use a file size larger than `kReadFileMaxChunkSize`.
|
||||
const buffer = Buffer.from('012'.repeat(2 ** 14));
|
||||
|
||||
(async () => {
|
||||
for (const Constructor of [Uint8Array, Uint16Array, Uint32Array]) {
|
||||
const array = new Constructor(buffer.buffer);
|
||||
await fsPromises.writeFile(dest, array);
|
||||
const data = await fsPromises.readFile(dest);
|
||||
assert.deepStrictEqual(data, buffer);
|
||||
}
|
||||
})().then(common.mustCall());
|
Loading…
Reference in New Issue