|
3 | 3 | const kWriteFileMaxChunkSize = 2 ** 14;
|
4 | 4 |
|
5 | 5 | const {
|
| 6 | + ArrayPrototypePush, |
6 | 7 | Error,
|
7 | 8 | MathMax,
|
8 | 9 | MathMin,
|
@@ -293,24 +294,46 @@ async function readFileHandle(filehandle, options) {
|
293 | 294 | if (size > kIoMaxLength)
|
294 | 295 | throw new ERR_FS_FILE_TOO_LARGE(size);
|
295 | 296 |
|
296 |
| - const chunks = []; |
297 |
| - const chunkSize = size === 0 ? |
298 |
| - kReadFileMaxChunkSize : |
299 |
| - MathMin(size, kReadFileMaxChunkSize); |
300 | 297 | let endOfFile = false;
|
| 298 | + let totalRead = 0; |
| 299 | + const noSize = size === 0; |
| 300 | + const buffers = []; |
| 301 | + const fullBuffer = noSize ? undefined : Buffer.allocUnsafeSlow(size); |
301 | 302 | do {
|
302 | 303 | if (signal && signal.aborted) {
|
303 | 304 | throw lazyDOMException('The operation was aborted', 'AbortError');
|
304 | 305 | }
|
305 |
| - const buf = Buffer.alloc(chunkSize); |
306 |
| - const { bytesRead, buffer } = |
307 |
| - await read(filehandle, buf, 0, chunkSize, -1); |
308 |
| - endOfFile = bytesRead === 0; |
309 |
| - if (bytesRead > 0) |
310 |
| - chunks.push(buffer.slice(0, bytesRead)); |
| 306 | + let buffer; |
| 307 | + let offset; |
| 308 | + let length; |
| 309 | + if (noSize) { |
| 310 | + buffer = Buffer.allocUnsafeSlow(kReadFileUnknownBufferLength); |
| 311 | + offset = 0; |
| 312 | + length = kReadFileUnknownBufferLength; |
| 313 | + } else { |
| 314 | + buffer = fullBuffer; |
| 315 | + offset = totalRead; |
| 316 | + length = MathMin(size - totalRead, kReadFileBufferLength); |
| 317 | + } |
| 318 | + |
| 319 | + const bytesRead = (await binding.read(filehandle.fd, buffer, offset, |
| 320 | + length, -1, kUsePromises)) || 0; |
| 321 | + totalRead += bytesRead; |
| 322 | + endOfFile = bytesRead === 0 || totalRead === size; |
| 323 | + if (noSize && bytesRead > 0) { |
| 324 | + const isBufferFull = bytesRead === kReadFileUnknownBufferLength; |
| 325 | + const chunkBuffer = isBufferFull ? buffer : buffer.slice(0, bytesRead); |
| 326 | + ArrayPrototypePush(buffers, chunkBuffer); |
| 327 | + } |
311 | 328 | } while (!endOfFile);
|
312 | 329 |
|
313 |
| - const result = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks); |
| 330 | + let result; |
| 331 | + if (size > 0) { |
| 332 | + result = totalRead === size ? fullBuffer : fullBuffer.slice(0, totalRead); |
| 333 | + } else { |
| 334 | + result = buffers.length === 1 ? buffers[0] : Buffer.concat(buffers, |
| 335 | + totalRead); |
| 336 | + } |
314 | 337 |
|
315 | 338 | return options.encoding ? result.toString(options.encoding) : result;
|
316 | 339 | }
|
|
0 commit comments