From 11819c7773d123efb8db836aefc73bde8c5f431a Mon Sep 17 00:00:00 2001 From: Antoine du HAMEL Date: Wed, 28 Mar 2018 19:15:52 +0200 Subject: [PATCH] fs: handle long files reading in fs.promises PR-URL: https://github.com/nodejs/node/pull/19643 Reviewed-By: James M Snell Reviewed-By: Tiancheng "Timothy" Gu Reviewed-By: Joyee Cheung Reviewed-By: Benjamin Gruenbaum Reviewed-By: Ruben Bridgewater --- lib/fs/promises.js | 14 ++++++----- test/parallel/test-fs-promises-readfile.js | 28 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 test/parallel/test-fs-promises-readfile.js diff --git a/lib/fs/promises.js b/lib/fs/promises.js index a1d805803ae..ba6c2b7aa64 100644 --- a/lib/fs/promises.js +++ b/lib/fs/promises.js @@ -147,15 +147,17 @@ async function readFileHandle(filehandle, options) { const chunks = []; const chunkSize = Math.min(size, 16384); - const buf = Buffer.alloc(chunkSize); let totalRead = 0; + let endOfFile = false; do { + const buf = Buffer.alloc(chunkSize); const { bytesRead, buffer } = - await read(filehandle, buf, 0, buf.length); - totalRead = bytesRead; - if (totalRead > 0) - chunks.push(buffer.slice(0, totalRead)); - } while (totalRead === chunkSize); + await read(filehandle, buf, 0, chunkSize, totalRead); + totalRead += bytesRead; + endOfFile = bytesRead !== chunkSize; + if (bytesRead > 0) + chunks.push(buffer.slice(0, bytesRead)); + } while (!endOfFile); const result = Buffer.concat(chunks); if (options.encoding) { diff --git a/test/parallel/test-fs-promises-readfile.js b/test/parallel/test-fs-promises-readfile.js new file mode 100644 index 00000000000..1bf49503c31 --- /dev/null +++ b/test/parallel/test-fs-promises-readfile.js @@ -0,0 +1,28 @@ +'use strict'; + +const common = require('../common'); + +const assert = require('assert'); +const path = require('path'); +const { writeFile, readFile } = require('fs/promises'); +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +const fn = path.join(tmpdir.path, 'large-file'); + +common.crashOnUnhandledRejection(); + +// Creating large buffer with random content +const buffer = Buffer.from( + Array.apply(null, { length: 16834 * 2 }) + .map(Math.random) + .map((number) => (number * (1 << 8))) +); + +// Writing buffer to a file then try to read it +writeFile(fn, buffer) + .then(() => readFile(fn)) + .then((readBuffer) => { + assert.strictEqual(readBuffer.equals(buffer), true); + }) + .then(common.mustCall());