Skip to content

[API Proposal]: Add new constructors to FileSystemEnumerable and FileSystemEnumerator allowing a search pattern string to be provided #127692

@benstevens48

Description

@benstevens48

Background and motivation

DirectoryInfo.GetFiles and related functions have a searchPattern string parameter for matching the file name. Historically, this matching was done in managed code (not at the OS-level), therefore it wasn't really necessary for FileSystemEnumerator/FileSystemEnumerable to take a search pattern string since matching could be done in the filter predicate. However, the OS (at least Windows), supports doing this filtering at the OS level, and this OS-level filtering is now implemented by #122947. Thus it is now much faster to use DirectoryInfo.GetFiles in a scenario where a search pattern applies (e.g. filtering by a single file extension), even though FileSystemEnumerator/FileSystemEnumerable are meant to be the most performant methods. Therefore I propose they should accept a search pattern string. The implementation should be quite easy since there is now an internal constructor for FileSystemEnumerator/FileSystemEnumerable which accepts the search pattern (for Windows - for other OSes it would have to make use of the matching filter used by DirectoryInfo, which should also be quite straightforward).

For reference, see related discussion here - #127501.

API Proposal

namespace System.IO.Enumeration;

public abstract class FileSystemEnumerator<TResult> : System.Runtime.ConstrainedExecution.CriticalFinalizerObject, System.Collections.Generic.IEnumerator<TResult>
{
    //Added searchPattern parameter to existing constructor
    public FileSystemEnumerator(string directory, System.IO.EnumerationOptions? options = default, string? searchPattern = default);
}

public class FileSystemEnumerable<TResult> : System.Collections.Generic.IEnumerable<TResult>
{
    //Added searchPattern parameter to existing constructor
    public FileSystemEnumerable(string directory, System.IO.Enumeration.FileSystemEnumerable<TResult>.FindTransform transform, System.IO.EnumerationOptions? options = default, string? searchPattern = default);
}

The searchPattern is in the same format as for DirectoryInfo.GetFiles.

API Usage

 var enumeration = new FileSystemEnumerable<string>(
    directory: Path.GetTempPath(), // search Temp directory
    transform: (ref FileSystemEntry entry) => entry.ToFullPath(), // map FileSystemEntry to string (see FileSystemEnumerable generic argument)
    options: new EnumerationOptions()
    {
        RecurseSubdirectories = true
    },
    searchPattern: "*.tmp")
{
    // The following predicate will be used to filter the file entries
    ShouldIncludePredicate = (ref FileSystemEntry entry) => !entry.IsDirectory
};

This is taken from the FileSystemEnumerable example and replaces the manual extension filter with a search pattern, which on Windows is now applied at the OS level.

Alternative Designs

Could make the searchPattern a property of FileSystemEnumerable/FileSystemEnumerator instead.

Risks

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    api-suggestionEarly API idea and discussion, it is NOT ready for implementationarea-System.IOuntriagedNew issue has not been triaged by the area owner

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions