diff --git a/lib/internal/fs/promises.js b/lib/internal/fs/promises.js index a938b382eb1268..60a28735a982ec 100644 --- a/lib/internal/fs/promises.js +++ b/lib/internal/fs/promises.js @@ -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); } diff --git a/test/parallel/test-fs-promises-writefile-typedarray.js b/test/parallel/test-fs-promises-writefile-typedarray.js new file mode 100644 index 00000000000000..32d9cffa236e57 --- /dev/null +++ b/test/parallel/test-fs-promises-writefile-typedarray.js @@ -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());