| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 180e3f6 commit b277776
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,9 +4,8 @@ | |||
| 4 | 4 | // See https://github.com/libuv/libuv/pull/1501. | |
| 5 | 5 | const kIoMaxLength = 2 ** 31 - 1; | |
| 6 | 6 | ||
| 7 | - // Note: This is different from kReadFileBufferLength used for non-promisified | ||
| 8 | - // fs.readFile. | ||
| 9 | - const kReadFileMaxChunkSize = 2 ** 14; | ||
| 7 | + const kReadFileBufferLength = 512 * 1024; | ||
| 8 | + const kReadFileUnknownBufferLength = 64 * 1024; | ||
| 10 | 9 | const kWriteFileMaxChunkSize = 2 ** 14; | |
| 11 | 10 | ||
| 12 | 11 | const { | |
@@ -316,25 +315,46 @@ async function readFileHandle(filehandle, options) { | |||
| 316 | 315 | if (size > kIoMaxLength) | |
| 317 | 316 | throw new ERR_FS_FILE_TOO_LARGE(size); | |
| 318 | 317 | ||
| 319 | - const chunks = []; | ||
| 320 | - let isFirstChunk = true; | ||
| 321 | - const firstChunkSize = size === 0 ? kReadFileMaxChunkSize : size; | ||
| 322 | - const chunkSize = MathMin(firstChunkSize, kReadFileMaxChunkSize); | ||
| 323 | 318 | let endOfFile = false; | |
| 319 | + let totalRead = 0; | ||
| 320 | + const noSize = size === 0; | ||
| 321 | + const buffers = []; | ||
| 322 | + const fullBuffer = noSize ? undefined : Buffer.allocUnsafeSlow(size); | ||
| 324 | 323 | do { | |
| 325 | 324 | if (signal?.aborted) { | |
| 326 | 325 | throw lazyDOMException('The operation was aborted', 'AbortError'); | |
| 327 | 326 | } | |
| 328 | - const buf = Buffer.alloc(isFirstChunk ? firstChunkSize : chunkSize); | ||
| 329 | - const { bytesRead, buffer } = | ||
| 330 | - await read(filehandle, buf, 0, buf.length, -1); | ||
| 331 | - endOfFile = bytesRead === 0; | ||
| 332 | - if (bytesRead > 0) | ||
| 333 | - ArrayPrototypePush(chunks, buffer.slice(0, bytesRead)); | ||
| 334 | - isFirstChunk = false; | ||
| 327 | + let buffer; | ||
| 328 | + let offset; | ||
| 329 | + let length; | ||
| 330 | + if (noSize) { | ||
| 331 | + buffer = Buffer.allocUnsafeSlow(kReadFileUnknownBufferLength); | ||
| 332 | + offset = 0; | ||
| 333 | + length = kReadFileUnknownBufferLength; | ||
| 334 | + } else { | ||
| 335 | + buffer = fullBuffer; | ||
| 336 | + offset = totalRead; | ||
| 337 | + length = MathMin(size - totalRead, kReadFileBufferLength); | ||
| 338 | + } | ||
| 339 | + | ||
| 340 | + const bytesRead = (await binding.read(filehandle.fd, buffer, offset, | ||
| 341 | + length, -1, kUsePromises)) || 0; | ||
| 342 | + totalRead += bytesRead; | ||
| 343 | + endOfFile = bytesRead === 0 || totalRead === size; | ||
| 344 | + if (noSize && bytesRead > 0) { | ||
| 345 | + const isBufferFull = bytesRead === kReadFileUnknownBufferLength; | ||
| 346 | + const chunkBuffer = isBufferFull ? buffer : buffer.slice(0, bytesRead); | ||
| 347 | + ArrayPrototypePush(buffers, chunkBuffer); | ||
| 348 | + } | ||
| 335 | 349 | } while (!endOfFile); | |
| 336 | 350 | ||
| 337 | - const result = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks); | ||
| 351 | + let result; | ||
| 352 | + if (size > 0) { | ||
| 353 | + result = totalRead === size ? fullBuffer : fullBuffer.slice(0, totalRead); | ||
| 354 | + } else { | ||
| 355 | + result = buffers.length === 1 ? buffers[0] : Buffer.concat(buffers, | ||
| 356 | + totalRead); | ||
| 357 | + } | ||
| 338 | 358 | ||
| 339 | 359 | return options.encoding ? result.toString(options.encoding) : result; | |
| 340 | 360 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,7 +10,7 @@ const { | |||
| 10 | 10 | open, | |
| 11 | 11 | readFile, | |
| 12 | 12 | writeFile, | |
| 13 | - truncate | ||
| 13 | + truncate, | ||
| 14 | 14 | } = fs.promises; | |
| 15 | 15 | const path = require('path'); | |
| 16 | 16 | const tmpdir = require('../common/tmpdir'); | |
@@ -64,6 +64,7 @@ async function doReadAndCancel() { | |||
| 64 | 64 | await assert.rejects(readFile(fileHandle, { signal }), { | |
| 65 | 65 | name: 'AbortError' | |
| 66 | 66 | }); | |
| 67 | + await fileHandle.close(); | ||
| 67 | 68 | } | |
| 68 | 69 | ||
| 69 | 70 | // Signal aborted on first tick | |
@@ -74,10 +75,11 @@ async function doReadAndCancel() { | |||
| 74 | 75 | fs.writeFileSync(filePathForHandle, buffer); | |
| 75 | 76 | const controller = new AbortController(); | |
| 76 | 77 | const { signal } = controller; | |
| 77 | - tick(1, () => controller.abort()); | ||
| 78 | + process.nextTick(() => controller.abort()); | ||
| 78 | 79 | await assert.rejects(readFile(fileHandle, { signal }), { | |
| 79 | 80 | name: 'AbortError' | |
| 80 | - }); | ||
| 81 | + }, 'tick-0'); | ||
| 82 | + await fileHandle.close(); | ||
| 81 | 83 | } | |
| 82 | 84 | ||
| 83 | 85 | // Signal aborted right before buffer read | |
@@ -90,10 +92,12 @@ async function doReadAndCancel() { | |||
| 90 | 92 | ||
| 91 | 93 | const controller = new AbortController(); | |
| 92 | 94 | const { signal } = controller; | |
| 93 | - tick(2, () => controller.abort()); | ||
| 95 | + tick(1, () => controller.abort()); | ||
| 94 | 96 | await assert.rejects(fileHandle.readFile({ signal, encoding: 'utf8' }), { | |
| 95 | 97 | name: 'AbortError' | |
| 96 | - }); | ||
| 98 | + }, 'tick-1'); | ||
| 99 | + | ||
| 100 | + await fileHandle.close(); | ||
| 97 | 101 | } | |
| 98 | 102 | ||
| 99 | 103 | // Validate file size is within range for reading | |
@@ -111,6 +115,7 @@ async function doReadAndCancel() { | |||
| 111 | 115 | name: 'RangeError', | |
| 112 | 116 | code: 'ERR_FS_FILE_TOO_LARGE' | |
| 113 | 117 | }); | |
| 118 | + await fileHandle.close(); | ||
| 114 | 119 | } | |
| 115 | 120 | } | |
| 116 | 121 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments