Jeninnet.FileQuery 1.2.1

Requires NuGet 6.0.0 or higher.

dotnet add package Jeninnet.FileQuery --version 1.2.1
                    
NuGet\Install-Package Jeninnet.FileQuery -Version 1.2.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Jeninnet.FileQuery" Version="1.2.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Jeninnet.FileQuery" Version="1.2.1" />
                    
Directory.Packages.props
<PackageReference Include="Jeninnet.FileQuery" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Jeninnet.FileQuery --version 1.2.1
                    
#r "nuget: Jeninnet.FileQuery, 1.2.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Jeninnet.FileQuery@1.2.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Jeninnet.FileQuery&version=1.2.1
                    
Install as a Cake Addin
#tool nuget:?package=Jeninnet.FileQuery&version=1.2.1
                    
Install as a Cake Tool

Jeninnet.FileQuery

GitHub Actions CI Workflow Status GitHub release GitHub contributors GitHub stars GitHub license

NuGet Version NuGet Downloads NuGet Downloads NuGet Downloads

Absolutely — here is the entire unified README, rewritten fully in English, cleanly structured, and placed inside a single fenced code block exactly as you requested.

Jeninnet.FileQuery is a high‑performance, deterministic, pattern‑driven file enumeration engine for .NET.

It supports GitIgnore, Glob, and flat Regex (r:) patterns, powered by a strict tokenization + invariant validation pipeline designed for correctness, scalability, and predictable behavior across multi‑million file trees.


✨ Overview

Jeninnet.FileQuery is not just a file filter — it is a pattern execution engine with:

  • Deterministic evaluation
  • Zero‑ambiguity parsing rules
  • Strict separation between scanning, validation, and execution
  • Scalable traversal for extremely large directory trees
  • Zero‑allocation hot paths using ReadOnlySpan<char>

🚀 Key Features

  • Ultra‑fast file enumeration (1M–2M files/sec)
  • GitIgnore‑compatible pattern engine
  • Glob pattern support
  • Flat Regex mode (r: prefix)
  • Hybrid auto‑detection
  • Deterministic include/exclude precedence
  • Sync + async APIs
  • Safe traversal (ignore inaccessible directories)
  • Full diagnostics + invariant validation
  • Immutable compiled pattern sets

📦 Installation

dotnet add package Jeninnet.FileQuery

⚡ Quick Start

Enumerate all .cs files

var engine = new FileQueryEngine();

var query = new FileQuery(
    rootPath: "C:/projects",
    options: new FileQueryEngineOptions {
        Patterns = new[] { "**/*.cs" }
    }
);

IEnumerable<string> results = engine.Execute(query);

Async enumeration

await foreach (var file in engine.ExecuteAsync(
    new FileQuery(
        rootPath: "/src",
        options: new FileQueryEngineOptions {
            Patterns = new[] { "**/*.md", "!bin/" }
        }
    ),
    cancellationToken
)) {
    Console.WriteLine(file);
}

🧩 Pattern Engines

1️⃣ GitIgnore Mode

Supports full GitIgnore semantics:

Feature Example Meaning
Wildcard * Match filename part
Recursive ** Match across directories
Directory-only bin/ Match directories only
Negation !src/app.cs Un-ignore a path
Root anchoring /src/*.cs Match only from root
Character classes [a-z] Character ranges

Example:

*.cs
!Program.cs
bin/

2️⃣ Glob Mode

Filesystem-style matching:

Syntax Meaning
* Any characters except /
? Any single character
** Recursive directories
[a-z] Character classes

Example:

**/*.txt
src/**/test?.md

3️⃣ Regex Mode (Flat)

Rules:

  • Must start with r:
  • No glob semantics
  • Applies to the full normalized path
  • Uses .NET Regex

Example:

r:^src\/.*\.cs$

4️⃣ Hybrid Mode

Automatic engine selection:

Pattern Engine
!bin/ GitIgnore
/src/*.cs GitIgnore
*.txt Glob
src/**/test?.md Glob
r:^data\d+$ Regex

📊 Pattern Engine Comparison

Feature GitIgnore Glob Regex (Flat)
Recursive **
? wildcard
Character classes
Negation !
Root anchoring /
Needs prefix No No Yes (r:)
Complexity Medium Low High
Best for Git-like filtering General file matching Advanced constraints

🧪 Advanced Examples

1️⃣ Exclude a folder but include a specific file inside it

bin/
!bin/tools/keep.dll

2️⃣ Match Markdown files everywhere except in docs/

**/*.md
!docs/**

3️⃣ Match JSON files starting with a lowercase letter

data/[a-z]*.json

4️⃣ Regex: match .cs files ending with a number

r:^src\/.*\d+\.cs$

5️⃣ Combine GitIgnore + Glob + Regex

!bin/
src/**/test?.cs
r:^tools\/.*\.ps1$

6️⃣ Limit recursion depth

MaxRecursionDepth = 2

7️⃣ Ignore access errors

IgnoreInaccessible = true

8️⃣ Match files inside alphabetic subfolders

src/[a-z]*/**/*.cs

9️⃣ Regex: match multiple extensions

r:^.*\.(cs|md|json)$

🔟 Match files inside numeric folders only

r:^logs\/\d+\/.*\.txt$

1️⃣1️⃣ Complex exclusion rules

**/*.cs
!**/obj/**
!**/bin/**
!**/temp/**

⚙️ FileQueryEngineOptions

Option Default Description
Patterns empty Pattern list
RecurseSubdirectories true Enable recursion
MaxRecursionDepth -1 Unlimited
IgnoreInaccessible true Skip permission errors
IgnoreCase platform Case sensitivity mode
PatternMatchingMode GitIgnore Default engine
PatternInterpretation Auto Hybrid detection

🧠 Architecture

Raw Pattern Text
        │
        ▼
PatternScanner (Tokenization only)
        │
        ▼
Invariant Validation Layer
        │
        ▼
CompiledPatternSet (Immutable)
        │
        ▼
HybridPathMatcher
     │
     ├── GitIgnoreMatcher
     ├── GlobMatcher
     └── RegexMatcher

📘 Appendix A — Pattern Grammar (Extended & Complete)

This appendix defines the formal grammar for all pattern engines supported by Jeninnet.FileQuery.


A.1 General Structure

pattern        ::= gitignore | glob | regex

A.2 GitIgnore Grammar

gitignore      ::= [negation] [root] segment ('/' segment)* [dironly]

negation       ::= '!' | ε
root           ::= '/' | ε
dironly        ::= '/' | ε
segment        ::= token+

Tokens

token          ::= literal
                 | '*'
                 | '?'
                 | '**'
                 | charclass

Character Classes

charclass      ::= '[' ['!'|'^'] classitem+ ']'
classitem      ::= literal | literal '-' literal

GitIgnore Rules

  • ** may match across directories
  • bin/ matches directories only
  • /foo anchors to root
  • !pattern negates
  • . and .. forbidden
  • Escaping supported

A.3 Glob Grammar

glob           ::= [negation] segment ('/' segment)*
negation       ::= '!' | ε
segment        ::= token+

Tokens

token          ::= literal | '*' | '?' | '**' | charclass

Glob Rules

  • * matches any chars except /
  • ? matches one char
  • ** matches directories
  • No root anchoring
  • No directory-only suffix

A.4 Regex Grammar

regex          ::= 'r:' regextext
regextext      ::= .+

Rules:

  • Must start with r:
  • Applies to full normalized path
  • Uses .NET Regex
  • No glob semantics

A.5 Hybrid Interpretation

if starts with "r:" → Regex
else if contains GitIgnore semantics → GitIgnore
else → Glob

A.6 Token Grammar (Shared)

literal         ::= any character except: '*', '?', '[', ']', '/', '!'
escaped         ::= '\' literal
token           ::= literal | escaped | '*' | '?' | '**' | charclass

A.7 Invalid Patterns

Pattern Reason
a**b ** must be isolated
[z-a] invalid range
../foo forbidden
./foo forbidden
**a invalid

A.8 Grammar Summary

pattern        ::= gitignore | glob | regex

gitignore      ::= [negation] [root] segment ('/' segment)* [dironly]
glob           ::= [negation] segment ('/' segment)*
regex          ::= 'r:' regextext

segment        ::= token+
token          ::= literal | '*' | '?' | '**' | charclass
charclass      ::= '[' ['!'|'^'] classitem+ ']'
classitem      ::= literal | literal '-' literal

❓ FAQ (Extended)

Does *.* work?

Yes.

Can I un-ignore a file inside an ignored folder?

Yes.

Is Regex mode using .NET Regex?

Yes.

Can Hybrid Mode be disabled?

Yes.

Can access errors be ignored?

Yes.

Can multiple pattern types be mixed?

Yes.

Are absolute paths allowed?

No.

Are . or .. allowed?

No.

Can I get diagnostics for invalid patterns?

Yes.

Does it scale?

Yes — multi‑million file trees.


📄 License

MIT License.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Jeninnet.FileQuery:

Package Downloads
Jeninnet.FileQuery.CommandLine

CLI tool for high-performance file system querying.

Jeninnet.FileQuery.DependencyInjection

Dependency Injection integration for Jeninnet.FileQuery

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.1 238 6/17/2026
1.2.0 251 6/17/2026
1.1.0 303 6/14/2026
1.0.0 314 6/2/2026