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
Background and motivation
DirectoryInfo.GetFilesand related functions have asearchPatternstring 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 forFileSystemEnumerator/FileSystemEnumerableto 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 useDirectoryInfo.GetFilesin a scenario where a search pattern applies (e.g. filtering by a single file extension), even thoughFileSystemEnumerator/FileSystemEnumerableare 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 forFileSystemEnumerator/FileSystemEnumerablewhich accepts the search pattern (for Windows - for other OSes it would have to make use of the matching filter used byDirectoryInfo, which should also be quite straightforward).For reference, see related discussion here - #127501.
API Proposal
The searchPattern is in the same format as for DirectoryInfo.GetFiles.
API Usage
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/FileSystemEnumeratorinstead.Risks
No response