| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 725a2b1 commit ad97314
8 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -283,6 +283,92 @@ synchronous use libuv's threadpool, which can have surprising and negative | |||
| 283 | 283 | performance implications for some applications. See the | |
| 284 | 284 | [`UV_THREADPOOL_SIZE`][] documentation for more information. | |
| 285 | 285 | ||
| 286 | + ## Class: fs.Dirent | ||
| 287 | + <!-- YAML | ||
| 288 | + added: REPLACEME | ||
| 289 | + --> | ||
| 290 | + | ||
| 291 | + When [`fs.readdir()`][] or [`fs.readdirSync()`][] is called with the | ||
| 292 | + `withFileTypes` option set to `true`, the resulting array is filled with | ||
| 293 | + `fs.Dirent` objects, rather than strings or `Buffers`. | ||
| 294 | + | ||
| 295 | + ### dirent.isBlockDevice() | ||
| 296 | + <!-- YAML | ||
| 297 | + added: REPLACEME | ||
| 298 | + --> | ||
| 299 | + | ||
| 300 | + * Returns: {boolean} | ||
| 301 | + | ||
| 302 | + Returns `true` if the `fs.Dirent` object describes a block device. | ||
| 303 | + | ||
| 304 | + ### dirent.isCharacterDevice() | ||
| 305 | + <!-- YAML | ||
| 306 | + added: REPLACEME | ||
| 307 | + --> | ||
| 308 | + | ||
| 309 | + * Returns: {boolean} | ||
| 310 | + | ||
| 311 | + Returns `true` if the `fs.Dirent` object describes a character device. | ||
| 312 | + | ||
| 313 | + ### dirent.isDirectory() | ||
| 314 | + <!-- YAML | ||
| 315 | + added: REPLACEME | ||
| 316 | + --> | ||
| 317 | + | ||
| 318 | + * Returns: {boolean} | ||
| 319 | + | ||
| 320 | + Returns `true` if the `fs.Dirent` object describes a file system | ||
| 321 | + directory. | ||
| 322 | + | ||
| 323 | + ### dirent.isFIFO() | ||
| 324 | + <!-- YAML | ||
| 325 | + added: REPLACEME | ||
| 326 | + --> | ||
| 327 | + | ||
| 328 | + * Returns: {boolean} | ||
| 329 | + | ||
| 330 | + Returns `true` if the `fs.Dirent` object describes a first-in-first-out | ||
| 331 | + (FIFO) pipe. | ||
| 332 | + | ||
| 333 | + ### dirent.isFile() | ||
| 334 | + <!-- YAML | ||
| 335 | + added: REPLACEME | ||
| 336 | + --> | ||
| 337 | + | ||
| 338 | + * Returns: {boolean} | ||
| 339 | + | ||
| 340 | + Returns `true` if the `fs.Dirent` object describes a regular file. | ||
| 341 | + | ||
| 342 | + ### dirent.isSocket() | ||
| 343 | + <!-- YAML | ||
| 344 | + added: REPLACEME | ||
| 345 | + --> | ||
| 346 | + | ||
| 347 | + * Returns: {boolean} | ||
| 348 | + | ||
| 349 | + Returns `true` if the `fs.Dirent` object describes a socket. | ||
| 350 | + | ||
| 351 | + ### dirent.isSymbolicLink() | ||
| 352 | + <!-- YAML | ||
| 353 | + added: REPLACEME | ||
| 354 | + --> | ||
| 355 | + | ||
| 356 | + * Returns: {boolean} | ||
| 357 | + | ||
| 358 | + Returns `true` if the `fs.Dirent` object describes a symbolic link. | ||
| 359 | + | ||
| 360 | + | ||
| 361 | + ### dirent.name | ||
| 362 | + <!-- YAML | ||
| 363 | + added: REPLACEME | ||
| 364 | + --> | ||
| 365 | + | ||
| 366 | + * {string|Buffer} | ||
| 367 | + | ||
| 368 | + The file name that this `fs.Dirent` object refers to. The type of this | ||
| 369 | + value is determined by the `options.encoding` passed to [`fs.readdir()`][] or | ||
| 370 | + [`fs.readdirSync()`][]. | ||
| 371 | + | ||
| 286 | 372 | ## Class: fs.FSWatcher | |
| 287 | 373 | <!-- YAML | |
| 288 | 374 | added: v0.5.8 | |
@@ -2299,9 +2385,10 @@ changes: | |||
| 2299 | 2385 | * `path` {string|Buffer|URL} | |
| 2300 | 2386 | * `options` {string|Object} | |
| 2301 | 2387 | * `encoding` {string} **Default:** `'utf8'` | |
| 2388 | + * `withFileTypes` {boolean} **Default:** `false` | ||
| 2302 | 2389 | * `callback` {Function} | |
| 2303 | 2390 | * `err` {Error} | |
| 2304 | - * `files` {string[]|Buffer[]} | ||
| 2391 | + * `files` {string[]|Buffer[]|fs.Dirent[]} | ||
| 2305 | 2392 | ||
| 2306 | 2393 | Asynchronous readdir(3). Reads the contents of a directory. | |
| 2307 | 2394 | The callback gets two arguments `(err, files)` where `files` is an array of | |
@@ -2312,6 +2399,9 @@ object with an `encoding` property specifying the character encoding to use for | |||
| 2312 | 2399 | the filenames passed to the callback. If the `encoding` is set to `'buffer'`, | |
| 2313 | 2400 | the filenames returned will be passed as `Buffer` objects. | |
| 2314 | 2401 | ||
| 2402 | + If `options.withFileTypes` is set to `true`, the `files` array will contain | ||
| 2403 | + [`fs.Dirent`][] objects. | ||
| 2404 | + | ||
| 2315 | 2405 | ## fs.readdirSync(path[, options]) | |
| 2316 | 2406 | <!-- YAML | |
| 2317 | 2407 | added: v0.1.21 | |
@@ -2325,7 +2415,8 @@ changes: | |||
| 2325 | 2415 | * `path` {string|Buffer|URL} | |
| 2326 | 2416 | * `options` {string|Object} | |
| 2327 | 2417 | * `encoding` {string} **Default:** `'utf8'` | |
| 2328 | - * Returns: {string[]} An array of filenames excluding `'.'` and `'..'`. | ||
| 2418 | + * `withFileTypes` {boolean} **Default:** `false` | ||
| 2419 | + * Returns: {string[]|Buffer[]|fs.Dirent[]} | ||
| 2329 | 2420 | ||
| 2330 | 2421 | Synchronous readdir(3). | |
| 2331 | 2422 | ||
@@ -2334,6 +2425,9 @@ object with an `encoding` property specifying the character encoding to use for | |||
| 2334 | 2425 | the filenames returned. If the `encoding` is set to `'buffer'`, | |
| 2335 | 2426 | the filenames returned will be passed as `Buffer` objects. | |
| 2336 | 2427 | ||
| 2428 | + If `options.withFileTypes` is set to `true`, the result will contain | ||
| 2429 | + [`fs.Dirent`][] objects. | ||
| 2430 | + | ||
| 2337 | 2431 | ## fs.readFile(path[, options], callback) | |
| 2338 | 2432 | <!-- YAML | |
| 2339 | 2433 | added: v0.1.29 | |
@@ -4611,6 +4705,7 @@ the file contents. | |||
| 4611 | 4705 | [`WriteStream`]: #fs_class_fs_writestream | |
| 4612 | 4706 | [`EventEmitter`]: events.html | |
| 4613 | 4707 | [`event ports`]: http://illumos.org/man/port_create | |
| 4708 | + [`fs.Dirent`]: #fs_class_fs_dirent | ||
| 4614 | 4709 | [`fs.FSWatcher`]: #fs_class_fs_fswatcher | |
| 4615 | 4710 | [`fs.Stats`]: #fs_class_fs_stats | |
| 4616 | 4711 | [`fs.access()`]: #fs_fs_access_path_mode_callback | |
@@ -4626,6 +4721,8 @@ the file contents. | |||
| 4626 | 4721 | [`fs.mkdtemp()`]: #fs_fs_mkdtemp_prefix_options_callback | |
| 4627 | 4722 | [`fs.open()`]: #fs_fs_open_path_flags_mode_callback | |
| 4628 | 4723 | [`fs.read()`]: #fs_fs_read_fd_buffer_offset_length_position_callback | |
| 4724 | + [`fs.readdir()`]: #fs_fs_readdir_path_options_callback | ||
| 4725 | + [`fs.readdirSync()`]: #fs_fs_readdirsync_path_options | ||
| 4629 | 4726 | [`fs.readFile()`]: #fs_fs_readfile_path_options_callback | |
| 4630 | 4727 | [`fs.readFileSync()`]: #fs_fs_readfilesync_path_options | |
| 4631 | 4728 | [`fs.realpath()`]: #fs_fs_realpath_path_options_callback | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -58,6 +58,8 @@ const { getPathFromURL } = require('internal/url'); | |||
| 58 | 58 | const internalUtil = require('internal/util'); | |
| 59 | 59 | const { | |
| 60 | 60 | copyObject, | |
| 61 | + Dirent, | ||
| 62 | + getDirents, | ||
| 61 | 63 | getOptions, | |
| 62 | 64 | nullCheck, | |
| 63 | 65 | preprocessSymlinkDestination, | |
@@ -736,8 +738,19 @@ function readdir(path, options, callback) { | |||
| 736 | 738 | validatePath(path); | |
| 737 | 739 | ||
| 738 | 740 | const req = new FSReqWrap(); | |
| 739 | - req.oncomplete = callback; | ||
| 740 | - binding.readdir(pathModule.toNamespacedPath(path), options.encoding, req); | ||
| 741 | + if (!options.withFileTypes) { | ||
| 742 | + req.oncomplete = callback; | ||
| 743 | + } else { | ||
| 744 | + req.oncomplete = (err, result) => { | ||
| 745 | + if (err) { | ||
| 746 | + callback(err); | ||
| 747 | + return; | ||
| 748 | + } | ||
| 749 | + getDirents(path, result, callback); | ||
| 750 | + }; | ||
| 751 | + } | ||
| 752 | + binding.readdir(pathModule.toNamespacedPath(path), options.encoding, | ||
| 753 | + !!options.withFileTypes, req); | ||
| 741 | 754 | } | |
| 742 | 755 | ||
| 743 | 756 | function readdirSync(path, options) { | |
@@ -746,9 +759,10 @@ function readdirSync(path, options) { | |||
| 746 | 759 | validatePath(path); | |
| 747 | 760 | const ctx = { path }; | |
| 748 | 761 | const result = binding.readdir(pathModule.toNamespacedPath(path), | |
| 749 | - options.encoding, undefined, ctx); | ||
| 762 | + options.encoding, !!options.withFileTypes, | ||
| 763 | + undefined, ctx); | ||
| 750 | 764 | handleErrorFromBinding(ctx); | |
| 751 | - return result; | ||
| 765 | + return options.withFileTypes ? getDirents(path, result) : result; | ||
| 752 | 766 | } | |
| 753 | 767 | ||
| 754 | 768 | function fstat(fd, options, callback) { | |
@@ -1773,6 +1787,7 @@ module.exports = fs = { | |||
| 1773 | 1787 | writeFileSync, | |
| 1774 | 1788 | write, | |
| 1775 | 1789 | writeSync, | |
| 1790 | + Dirent, | ||
| 1776 | 1791 | Stats, | |
| 1777 | 1792 | ||
| 1778 | 1793 | // Stream constructors | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,6 +18,7 @@ const { getPathFromURL } = require('internal/url'); | |||
| 18 | 18 | const { isUint8Array } = require('internal/util/types'); | |
| 19 | 19 | const { | |
| 20 | 20 | copyObject, | |
| 21 | + getDirents, | ||
| 21 | 22 | getOptions, | |
| 22 | 23 | getStatsFromBinding, | |
| 23 | 24 | nullCheck, | |
@@ -36,10 +37,13 @@ const { | |||
| 36 | 37 | validateUint32 | |
| 37 | 38 | } = require('internal/validators'); | |
| 38 | 39 | const pathModule = require('path'); | |
| 40 | + const { promisify } = require('internal/util'); | ||
| 39 | 41 | ||
| 40 | 42 | const kHandle = Symbol('handle'); | |
| 41 | 43 | const { kUsePromises } = binding; | |
| 42 | 44 | ||
| 45 | + const getDirectoryEntriesPromise = promisify(getDirents); | ||
| 46 | + | ||
| 43 | 47 | class FileHandle { | |
| 44 | 48 | constructor(filehandle) { | |
| 45 | 49 | this[kHandle] = filehandle; | |
@@ -294,8 +298,12 @@ async function readdir(path, options) { | |||
| 294 | 298 | options = getOptions(options, {}); | |
| 295 | 299 | path = getPathFromURL(path); | |
| 296 | 300 | validatePath(path); | |
| 297 | - return binding.readdir(pathModule.toNamespacedPath(path), | ||
| 298 | - options.encoding, kUsePromises); | ||
| 301 | + const result = await binding.readdir(pathModule.toNamespacedPath(path), | ||
| 302 | + options.encoding, !!options.withTypes, | ||
| 303 | + kUsePromises); | ||
| 304 | + return options.withFileTypes ? | ||
| 305 | + getDirectoryEntriesPromise(path, result) : | ||
| 306 | + result; | ||
| 299 | 307 | } | |
| 300 | 308 | ||
| 301 | 309 | async function readlink(path, options) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -12,6 +12,8 @@ const { | |||
| 12 | 12 | const { isUint8Array } = require('internal/util/types'); | |
| 13 | 13 | const pathModule = require('path'); | |
| 14 | 14 | const util = require('util'); | |
| 15 | + const kType = Symbol('type'); | ||
| 16 | + const kStats = Symbol('stats'); | ||
| 15 | 17 | ||
| 16 | 18 | const { | |
| 17 | 19 | O_APPEND, | |
@@ -31,24 +33,135 @@ const { | |||
| 31 | 33 | S_IFREG, | |
| 32 | 34 | S_IFSOCK, | |
| 33 | 35 | UV_FS_SYMLINK_DIR, | |
| 34 | - UV_FS_SYMLINK_JUNCTION | ||
| 36 | + UV_FS_SYMLINK_JUNCTION, | ||
| 37 | + UV_DIRENT_UNKNOWN, | ||
| 38 | + UV_DIRENT_FILE, | ||
| 39 | + UV_DIRENT_DIR, | ||
| 40 | + UV_DIRENT_LINK, | ||
| 41 | + UV_DIRENT_FIFO, | ||
| 42 | + UV_DIRENT_SOCKET, | ||
| 43 | + UV_DIRENT_CHAR, | ||
| 44 | + UV_DIRENT_BLOCK | ||
| 35 | 45 | } = process.binding('constants').fs; | |
| 36 | 46 | ||
| 37 | 47 | const isWindows = process.platform === 'win32'; | |
| 38 | 48 | ||
| 49 | + let fs; | ||
| 50 | + function lazyLoadFs() { | ||
| 51 | + if (!fs) { | ||
| 52 | + fs = require('fs'); | ||
| 53 | + } | ||
| 54 | + return fs; | ||
| 55 | + } | ||
| 56 | + | ||
| 39 | 57 | function assertEncoding(encoding) { | |
| 40 | 58 | if (encoding && !Buffer.isEncoding(encoding)) { | |
| 41 | 59 | throw new ERR_INVALID_OPT_VALUE_ENCODING(encoding); | |
| 42 | 60 | } | |
| 43 | 61 | } | |
| 44 | 62 | ||
| 63 | + class Dirent { | ||
| 64 | + constructor(name, type) { | ||
| 65 | + this.name = name; | ||
| 66 | + this[kType] = type; | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + isDirectory() { | ||
| 70 | + return this[kType] === UV_DIRENT_DIR; | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + isFile() { | ||
| 74 | + return this[kType] === UV_DIRENT_FILE; | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + isBlockDevice() { | ||
| 78 | + return this[kType] === UV_DIRENT_BLOCK; | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + isCharacterDevice() { | ||
| 82 | + return this[kType] === UV_DIRENT_CHAR; | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + isSymbolicLink() { | ||
| 86 | + return this[kType] === UV_DIRENT_LINK; | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + isFIFO() { | ||
| 90 | + return this[kType] === UV_DIRENT_FIFO; | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + isSocket() { | ||
| 94 | + return this[kType] === UV_DIRENT_SOCKET; | ||
| 95 | + } | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + class DirentFromStats extends Dirent { | ||
| 99 | + constructor(name, stats) { | ||
| 100 | + super(name, null); | ||
| 101 | + this[kStats] = stats; | ||
| 102 | + } | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + for (const name of Reflect.ownKeys(Dirent.prototype)) { | ||
| 106 | + if (name === 'constructor') { | ||
| 107 | + continue; | ||
| 108 | + } | ||
| 109 | + DirentFromStats.prototype[name] = function() { | ||
| 110 | + return this[kStats][name](); | ||
| 111 | + }; | ||
| 112 | + } | ||
| 113 | + | ||
| 45 | 114 | function copyObject(source) { | |
| 46 | 115 | var target = {}; | |
| 47 | 116 | for (var key in source) | |
| 48 | 117 | target[key] = source[key]; | |
| 49 | 118 | return target; | |
| 50 | 119 | } | |
| 51 | 120 | ||
| 121 | + function getDirents(path, [names, types], callback) { | ||
| 122 | + var i; | ||
| 123 | + if (typeof callback == 'function') { | ||
| 124 | + const len = names.length; | ||
| 125 | + let toFinish = 0; | ||
| 126 | + for (i = 0; i < len; i++) { | ||
| 127 | + const type = types[i]; | ||
| 128 | + if (type === UV_DIRENT_UNKNOWN) { | ||
| 129 | + const name = names[i]; | ||
| 130 | + const idx = i; | ||
| 131 | + toFinish++; | ||
| 132 | + lazyLoadFs().stat(pathModule.resolve(path, name), (err, stats) => { | ||
| 133 | + if (err) { | ||
| 134 | + callback(err); | ||
| 135 | + return; | ||
| 136 | + } | ||
| 137 | + names[idx] = new DirentFromStats(name, stats); | ||
| 138 | + if (--toFinish === 0) { | ||
| 139 | + callback(null, names); | ||
| 140 | + } | ||
| 141 | + }); | ||
| 142 | + } else { | ||
| 143 | + names[i] = new Dirent(names[i], types[i]); | ||
| 144 | + } | ||
| 145 | + } | ||
| 146 | + if (toFinish === 0) { | ||
| 147 | + callback(null, names); | ||
| 148 | + } | ||
| 149 | + } else { | ||
| 150 | + const len = names.length; | ||
| 151 | + for (i = 0; i < len; i++) { | ||
| 152 | + const type = types[i]; | ||
| 153 | + if (type === UV_DIRENT_UNKNOWN) { | ||
| 154 | + const name = names[i]; | ||
| 155 | + const stats = lazyLoadFs().statSync(pathModule.resolve(path, name)); | ||
| 156 | + names[i] = new DirentFromStats(name, stats); | ||
| 157 | + } else { | ||
| 158 | + names[i] = new Dirent(names[i], types[i]); | ||
| 159 | + } | ||
| 160 | + } | ||
| 161 | + return names; | ||
| 162 | + } | ||
| 163 | + } | ||
| 164 | + | ||
| 52 | 165 | function getOptions(options, defaultOptions) { | |
| 53 | 166 | if (options === null || options === undefined || | |
| 54 | 167 | typeof options === 'function') { | |
@@ -341,6 +454,8 @@ function validatePath(path, propName = 'path') { | |||
| 341 | 454 | module.exports = { | |
| 342 | 455 | assertEncoding, | |
| 343 | 456 | copyObject, | |
| 457 | + Dirent, | ||
| 458 | + getDirents, | ||
| 344 | 459 | getOptions, | |
| 345 | 460 | nullCheck, | |
| 346 | 461 | preprocessSymlinkDestination, | |
| Back | FazBrowse Home | New Git URL |
0 commit comments