patterncsharpMinor
Get list of files in directory with exclude option
Viewed 0 times
directorywithoptiongetfileslistexclude
Problem
This method returns the list of files (absolute path) in a folder (or tree). It allows filtering by extensions or filenames.
The method receives the following parameters:
The method return files that doesn't appear in
The method receives the following parameters:
string path: folder path to scan for files.
string[] exclude: can contain filenames such as"read.me"or extensions such as"*.jpg".
SearchOption searchOption:TopDirectoryOnlyto scan only the specified folder orAllDirectoriesto scan tree folder under the specified path.
The method return files that doesn't appear in
exclude array and a) hasn't extension, or b) extension doesn't appear in exclude array.public static IEnumerable GetFiles(string path, string[] exclude, SearchOption searchOption = SearchOption.AllDirectories)
{
IEnumerable files = Directory.EnumerateFiles(path, "*.*", searchOption);
var resultFiles = new List();
if (exclude.Length > 0)
{
foreach (var filename in files)
{
string extension = Path.GetExtension(filename);
if (Array.IndexOf(exclude, Path.GetFileName(filename)) >= 0)
{
continue;
}
if (string.IsNullOrEmpty(extension) || Array.IndexOf(exclude, "*" + extension) < 0)
{
resultFiles.Add(filename);
}
}
}
return resultFiles;
}Solution
You're already returning an
MSDN on
I don't like that both filenames and extensions are in the same array. If you have 1 extension and 5000 files that have to be excluded, it will iterate over 5000 files (if you have bad luck) for no reason.
I would consider using the
I prefer
If there is nothing to exclude, you won't include anything either.
A new implementation might look like this:
IEnumerable so you might as well turn it into an iterator block. Discard the local resultFiles and simply use yield return filename.MSDN on
yieldI don't like that both filenames and extensions are in the same array. If you have 1 extension and 5000 files that have to be excluded, it will iterate over 5000 files (if you have bad luck) for no reason.
I would consider using the
.Contains() extension method: it's just more expressive than Array.IndexOf and should be no difference in performance.I prefer
string.IsNullOrWhiteSpace since that also takes care of.. well.. whitespace. You never know if the pesky QA departement tries something like that.IEnumerable files = Directory.EnumerateFiles(path, "*.*", searchOption);
if (exclude.Length > 0)
{
}
return resultFiles;If there is nothing to exclude, you won't include anything either.
A new implementation might look like this:
public static IEnumerable GetFiles(string path, IEnumerable excludedFiles, IEnumerable excludedExtensions, SearchOption searchOption = SearchOption.AllDirectories)
{
var files = Directory.EnumerateFiles(path, "*.*", searchOption);
foreach(var file in files)
{
if(excludedFiles.Contains(file))
{
continue;
}
if(excludedExtensions.Contains(Path.GetExtension(file)))
{
continue;
}
yield return file;
}
}Code Snippets
IEnumerable<string> files = Directory.EnumerateFiles(path, "*.*", searchOption);
if (exclude.Length > 0)
{
}
return resultFiles;public static IEnumerable<string> GetFiles(string path, IEnumerable<string> excludedFiles, IEnumerable<string> excludedExtensions, SearchOption searchOption = SearchOption.AllDirectories)
{
var files = Directory.EnumerateFiles(path, "*.*", searchOption);
foreach(var file in files)
{
if(excludedFiles.Contains(file))
{
continue;
}
if(excludedExtensions.Contains(Path.GetExtension(file)))
{
continue;
}
yield return file;
}
}Context
StackExchange Code Review Q#87662, answer score: 7
Revisions (0)
No revisions yet.