Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

fs.readdir() with filter, recursion, absolute paths, promises, streams, and more!

License

NotificationsYou must be signed in to change notification settings

JS-DevTools/readdir-enhanced

Repository files navigation

Cross-Platform CompatibilityBuild Status

Coverage StatusDependencies

npmLicenseBuy us a tree

Features

Example

importreaddirfrom"@jsdevtools/readdir-enhanced";importthrough2from"through2";// Synchronous APIletfiles=readdir.sync("my/directory");// Callback APIreaddir.async("my/directory",(err,files)=>{ ...});// Promises APIreaddir.async("my/directory").then((files)=>{ ...}).catch((err)=>{ ...});// Async/Await APIletfiles=awaitreaddir.async("my/directory");// Async Iterator APIforawait(letitemofreaddir.iterator("my/directory")){  ...}// EventEmitter APIreaddir.stream("my/directory").on("data",(path)=>{ ...}).on("file",(path)=>{ ...}).on("directory",(path)=>{ ...}).on("symlink",(path)=>{ ...}).on("error",(err)=>{ ...});// Streaming APIletstream=readdir.stream("my/directory").pipe(through2.obj(function(data,enc,next){console.log(data);this.push(data);next();});

Installation

Install usingnpm:

npm install @jsdevtools/readdir-enhanced

Pick Your API

Readdir Enhanced has multiple APIs, so you can pick whichever one you prefer. Here are some things to consider about each API:

FunctionReturnsSyntaxBlocks the thread?Buffers results?
readdirSync()
readdir.sync()
ArraySynchronousyesyes
readdir()
readdir.async()
readdirAsync()
Promiseasync/await
Promise.then()
callback
noyes
readdir.iterator()
readdirIterator()
Iteratorfor await...ofnono
readdir.stream()
readdirStream()
Readable Streamstream.on("data")
stream.read()
stream.pipe()
nono

Blocking the Thread

The synchronous API blocks the thread until all results have been read. Only use this if you know the directory does not contain many items, or if your program needs the results before it can do anything else.

Buffered Results

Some APIs buffer the results, which means you get all the results at once (as an array). This can be more convenient to work with, but it can also consume a significant amount of memory, depending on how many results there are. The non-buffered APIs return each result to you one-by-one, which means you can start processing the results even while the directory is still being read.

Alias Exports

Theexample above imported thereaddir default export and used its properties, such asreaddir.sync orreaddir.async to call specific APIs. For convenience, each of the different APIs is exported as a named function that you can import directly.

  • readdir.sync() is also exported asreaddirSync()
  • readdir.async() is also exported asreaddirAsync()
  • readdir.iterator() is also exported asreaddirIterator()
  • readdir.stream() is also exported asreaddirStream()

Here's how to import named exports rather than the default export:

import{readdirSync,readdirAsync,readdirIterator,readdirStream}from"@jsdevtools/readdir-enhanced";

Enhanced Features

Readdir Enhanced adds several features to the built-infs.readdir() function. All of the enhanced features are opt-in, which makes Readdir Enhancedfully backward compatible by default. You can enable any of the features by passing-in anoptions argument as the second parameter.

Crawl Subdirectories

By default, Readdir Enhanced will only return the top-level contents of the starting directory. But you can set thedeep option to recursively traverse the subdirectories and return their contents as well.

Crawl ALL subdirectories

Thedeep option can be set totrue to traverse the entire directory structure.

importreaddirfrom"@jsdevtools/readdir-enhanced";readdir("my/directory",{deep:true},(err,files)=>{console.log(files);// => subdir1// => subdir1/file.txt// => subdir1/subdir2// => subdir1/subdir2/file.txt// => subdir1/subdir2/subdir3// => subdir1/subdir2/subdir3/file.txt});

Crawl to a specific depth

Thedeep option can be set to a number to only traverse that many levels deep. For example, callingreaddir("my/directory", {deep: 2}) will returnsubdir1/file.txt andsubdir1/subdir2/file.txt, but itwon't returnsubdir1/subdir2/subdir3/file.txt.

importreaddirfrom"@jsdevtools/readdir-enhanced";readdir("my/directory",{deep:2},(err,files)=>{console.log(files);// => subdir1// => subdir1/file.txt// => subdir1/subdir2// => subdir1/subdir2/file.txt// => subdir1/subdir2/subdir3});

Crawl subdirectories by name

For simple use-cases, you can use aregular expression or aglob pattern to crawl only the directories whose path matches the pattern. The path is relative to the starting directory by default, but you can customize this viaoptions.basePath.

NOTE: Glob patternsalways use forward-slashes, even on Windows. Thisdoes not apply to regular expressions though. Regular expressions should use the appropraite path separator for the environment. Or, you can match both types of separators using[\\/].

importreaddirfrom"@jsdevtools/readdir-enhanced";// Only crawl the "lib" and "bin" subdirectories// (notice that the "node_modules" subdirectory does NOT get crawled)readdir("my/directory",{deep:/lib|bin/},(err,files)=>{console.log(files);// => bin// => bin/cli.js// => lib// => lib/index.js// => node_modules// => package.json});

Custom recursion logic

For more advanced recursion, you can set thedeep option to a function that accepts anfs.Stats object and returns a truthy value if the starting directory should be crawled.

NOTE: Thefs.Stats object that's passed to the function has additionalpath anddepth properties. Thepath is relative to the starting directory by default, but you can customize this viaoptions.basePath. Thedepth is the number of subdirectories beneath the base path (seeoptions.deep).

importreaddirfrom"@jsdevtools/readdir-enhanced";// Crawl all subdirectories, except "node_modules"functionignoreNodeModules(stats){returnstats.path.indexOf("node_modules")===-1;}readdir("my/directory",{deep:ignoreNodeModules},(err,files)=>{console.log(files);// => bin// => bin/cli.js// => lib// => lib/index.js// => node_modules// => package.json});

Filtering

Thefilter option lets you limit the results based on any criteria you want.

Filter by name

For simple use-cases, you can use aregular expression or aglob pattern to filter items by their path. The path is relative to the starting directory by default, but you can customize this viaoptions.basePath.

NOTE: Glob patternsalways use forward-slashes, even on Windows. Thisdoes not apply to regular expressions though. Regular expressions should use the appropraite path separator for the environment. Or, you can match both types of separators using[\\/].

importreaddirfrom"@jsdevtools/readdir-enhanced";// Find all .txt filesreaddir("my/directory",{filter:"*.txt"});// Find all package.json filesreaddir("my/directory",{filter:"**/package.json",deep:true});// Find everything with at least one number in the namereaddir("my/directory",{filter:/\d+/});

Custom filtering logic

For more advanced filtering, you can specify a filter function that accepts anfs.Stats object and returns a truthy value if the item should be included in the results.

NOTE: Thefs.Stats object that's passed to the filter function has additionalpath anddepth properties. Thepath is relative to the starting directory by default, but you can customize this viaoptions.basePath. Thedepth is the number of subdirectories beneath the base path (seeoptions.deep).

importreaddirfrom"@jsdevtools/readdir-enhanced";// Only return file names containing an underscorefunctionmyFilter(stats){returnstats.isFile()&&stats.path.indexOf("_")>=0;}readdir("my/directory",{filter:myFilter},(err,files)=>{console.log(files);// => __myFile.txt// => my_other_file.txt// => img_1.jpg// => node_modules});

Getfs.Stats objects instead of strings

All of the Readdir Enhanced functions listed above return an array of strings (paths). But in some situations, the path isn't enough information. Setting thestats option returns an array offs.Stats objects instead of path strings. Thefs.Stats object contains all sorts of useful information, such as the size, the creation date/time, and helper methods such asisFile(),isDirectory(),isSymbolicLink(), etc.

NOTE: Thefs.Stats objects that are returned also have additionalpath anddepth properties. Thepath is relative to the starting directory by default, but you can customize this viaoptions.basePath. Thedepth is the number of subdirectories beneath the base path (seeoptions.deep).

importreaddirfrom"@jsdevtools/readdir-enhanced";readdir("my/directory",{stats:true},(err,stats)=>{for(letstatofstats){console.log(`${stat.path} was created at${stat.birthtime}`);}});

Base Path

By default all Readdir Enhanced functions return paths that are relative to the starting directory. But you can use thebasePath option to customize this. ThebasePath will be prepended to all of the returned paths. One common use-case for this is to setbasePath to the absolute path of the starting directory, so that all of the returned paths will be absolute.

importreaddirfrom"@jsdevtools/readdir-enhanced";import{resolve}from"path";// Get absolute pathsletabsPath=resolve("my/dir");readdir("my/directory",{basePath:absPath},(err,files)=>{console.log(files);// => /absolute/path/to/my/directory/file1.txt// => /absolute/path/to/my/directory/file2.txt// => /absolute/path/to/my/directory/subdir});// Get paths relative to the working directoryreaddir("my/directory",{basePath:"my/directory"},(err,files)=>{console.log(files);// => my/directory/file1.txt// => my/directory/file2.txt// => my/directory/subdir});

Path Separator

By default, Readdir Enhanced uses the correct path separator for your OS (\ on Windows,/ on Linux & MacOS). But you can set thesep option to any separator character(s) that you want to use instead. This is usually used to ensure consistent path separators across different OSes.

importreaddirfrom"@jsdevtools/readdir-enhanced";// Always use Windows path separatorsreaddir("my/directory",{sep:"\\",deep:true},(err,files)=>{console.log(files);// => subdir1// => subdir1\file.txt// => subdir1\subdir2// => subdir1\subdir2\file.txt// => subdir1\subdir2\subdir3// => subdir1\subdir2\subdir3\file.txt});

Custom FS methods

By default, Readdir Enhanced uses the defaultNode.js FileSystem module for methods likefs.stat,fs.readdir andfs.lstat. But in some situations, you can want to use your own FS methods (FTP, SSH, remote drive and etc). So you can provide your own implementation of FS methods by settingoptions.fs or specific methods, such asoptions.fs.stat.

importreaddirfrom"@jsdevtools/readdir-enhanced";functionmyCustomReaddirMethod(dir,callback){callback(null,["__myFile.txt"]);}letoptions={fs:{readdir:myCustomReaddirMethod}};readdir("my/directory",options,(err,files)=>{console.log(files);// => __myFile.txt});

Backward Compatible

Readdir Enhanced is fully backward-compatible with Node.js' built-infs.readdir() andfs.readdirSync() functions, so you can use it as a drop-in replacement in existing projects without affecting existing functionality, while still being able to use the enhanced features as needed.

import{readdir,readdirSync}from"@jsdevtools/readdir-enhanced";// Use it just like Node's built-in fs.readdir functionreaddir("my/directory",(er,files)=>{ ...});// Use it just like Node's built-in fs.readdirSync functionletfiles=readdirSync("my/directory");

A Note on Streams

The Readdir Enhanced streaming API follows the Node.js streaming API. A lot of questions around the streaming API can be answered by reading theNode.js documentation.. However, we've tried to answer the most common questions here.

Stream Events

All events in the Node.js streaming API are supported by Readdir Enhanced. These events include "end", "close", "drain", "error", plus more.An exhaustive list of events is available in the Node.js documentation.

Detect when the Stream has finished

Using these events, we can detect when the stream has finished reading files.

importreaddirfrom"@jsdevtools/readdir-enhanced";// Build the stream using the Streaming APIletstream=readdir.stream("my/directory").on("data",(path)=>{ ...});// Listen to the end event to detect the end of the streamstream.on("end",()=>{console.log("Stream finished!");});

Paused Streams vs. Flowing Streams

As with all Node.js streams, a Readdir Enhanced stream starts in "paused mode". For the stream to start emitting files, you'll need to switch it to "flowing mode".

There are many ways to trigger flowing mode, such as adding astream.data() handler, usingstream.pipe() or callingstream.resume().

Unless you trigger flowing mode, your stream will stay paused and you won't receive any file events.

More information on paused vs. flowing mode can be found in the Node.js documentation.

Contributing

Contributions, enhancements, and bug-fixes are welcome!Open an issue on GitHub andsubmit a pull request.

Building

To build the project locally on your computer:

  1. Clone this repo
    git clone https://github.com/JS-DevTools/readdir-enhanced.git

  2. Install dependencies
    npm install

  3. Run the tests
    npm test

License

Readdir Enhanced is 100% free and open-source, under theMIT license. Use it however you want.

This package isTreeware. If you use it in production, then we ask that youbuy the world a tree to thank us for our work. By contributing to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats.

Big Thanks To

Thanks to these awesome companies for their support of Open Source developers ❤

Travis CISauceLabsCoveralls

About

fs.readdir() with filter, recursion, absolute paths, promises, streams, and more!

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors4

  •  
  •  
  •  
  •  

[8]ページ先頭

©2009-2025 Movatter.jp