EnumerateFileSystemInfos uses EnumerationOptions (#6933)

* Changed EnumerateFileSystemInfos to EnumerationOptions we don't have to catch the exceptions ourself.

* Change Matchtype to mimic old search method.

Co-authored-by: p-storm <paul.de.man@gmail.com>
This commit is contained in:
P-Storm
2020-10-07 18:25:29 +02:00
committed by GitHub
parent 8b66932036
commit 163a699bff
4 changed files with 23 additions and 49 deletions

View File

@@ -42,8 +42,8 @@ namespace Microsoft.Plugin.Folder.UnitTests
queryFileSystemInfoMock.Setup(r => r.Exists(It.IsAny<string>())) queryFileSystemInfoMock.Setup(r => r.Exists(It.IsAny<string>()))
.Returns<string>(path => ContainsDirectory(path)); .Returns<string>(path => ContainsDirectory(path));
queryFileSystemInfoMock.Setup(r => r.MatchFileSystemInfo(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<SearchOption>())) queryFileSystemInfoMock.Setup(r => r.MatchFileSystemInfo(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>()))
.Returns<string, string, SearchOption>(MatchFileSystemInfo); .Returns<string, string, bool>(MatchFileSystemInfo);
_queryFileSystemInfoMock = queryFileSystemInfoMock; _queryFileSystemInfoMock = queryFileSystemInfoMock;
} }
@@ -66,25 +66,23 @@ namespace Microsoft.Plugin.Folder.UnitTests
return trimEnd; return trimEnd;
} }
private static IEnumerable<DisplayFileInfo> MatchFileSystemInfo(string search, string incompleteName, SearchOption searchOption) private static IEnumerable<DisplayFileInfo> MatchFileSystemInfo(string search, string incompleteName, bool isRecursive)
{ {
Func<string, bool> folderSearchFunc; Func<string, bool> folderSearchFunc;
Func<string, bool> fileSearchFunc; Func<string, bool> fileSearchFunc;
switch (searchOption) switch (isRecursive)
{ {
case SearchOption.TopDirectoryOnly: case false:
folderSearchFunc = s => s.Equals(search, StringComparison.CurrentCultureIgnoreCase); folderSearchFunc = s => s.Equals(search, StringComparison.CurrentCultureIgnoreCase);
var regexSearch = TrimDirectoryEnd(search); var regexSearch = TrimDirectoryEnd(search);
fileSearchFunc = s => Regex.IsMatch(s, $"^{Regex.Escape(regexSearch)}[^\\\\]*$"); fileSearchFunc = s => Regex.IsMatch(s, $"^{Regex.Escape(regexSearch)}[^\\\\]*$");
break; break;
case SearchOption.AllDirectories: case true:
folderSearchFunc = s => s.StartsWith(search, StringComparison.CurrentCultureIgnoreCase); folderSearchFunc = s => s.StartsWith(search, StringComparison.CurrentCultureIgnoreCase);
fileSearchFunc = s => s.StartsWith(search, StringComparison.CurrentCultureIgnoreCase); fileSearchFunc = s => s.StartsWith(search, StringComparison.CurrentCultureIgnoreCase);
break; break;
default:
throw new ArgumentOutOfRangeException(nameof(searchOption), searchOption, null);
} }
var directories = DirectoryExist.Where(s => folderSearchFunc(s)) var directories = DirectoryExist.Where(s => folderSearchFunc(s))

View File

@@ -10,6 +10,6 @@ namespace Microsoft.Plugin.Folder.Sources
{ {
public interface IQueryFileSystemInfo : IDirectoryWrapper public interface IQueryFileSystemInfo : IDirectoryWrapper
{ {
IEnumerable<DisplayFileInfo> MatchFileSystemInfo(string search, string incompleteName, SearchOption searchOption); IEnumerable<DisplayFileInfo> MatchFileSystemInfo(string search, string incompleteName, bool isRecursive);
} }
} }

View File

@@ -12,41 +12,22 @@ namespace Microsoft.Plugin.Folder.Sources
{ {
public class QueryFileSystemInfo : DirectoryWrapper, IQueryFileSystemInfo public class QueryFileSystemInfo : DirectoryWrapper, IQueryFileSystemInfo
{ {
public IEnumerable<DisplayFileInfo> MatchFileSystemInfo(string search, string incompleteName, SearchOption searchOption) public IEnumerable<DisplayFileInfo> MatchFileSystemInfo(string search, string incompleteName, bool isRecursive)
{ {
// search folder and add results // search folder and add results
var directoryInfo = new DirectoryInfo(search); var directoryInfo = new DirectoryInfo(search);
var fileSystemInfos = directoryInfo.EnumerateFileSystemInfos(incompleteName, searchOption); var fileSystemInfos = directoryInfo.EnumerateFileSystemInfos(incompleteName, new EnumerationOptions()
return SafeEnumerateFileSystemInfos(fileSystemInfos)
.Where(fileSystemInfo => (fileSystemInfo.Attributes & FileAttributes.Hidden) != FileAttributes.Hidden)
.Select(CreateDisplayFileInfo);
}
private static IEnumerable<FileSystemInfo> SafeEnumerateFileSystemInfos(IEnumerable<FileSystemInfo> fileSystemInfos)
{
using (var enumerator = fileSystemInfos.GetEnumerator())
{ {
while (true) MatchType = MatchType.Win32,
{ RecurseSubdirectories = isRecursive,
FileSystemInfo currentFileSystemInfo; IgnoreInaccessible = true,
try ReturnSpecialDirectories = false,
{ AttributesToSkip = FileAttributes.Hidden,
if (!enumerator.MoveNext()) MatchCasing = MatchCasing.PlatformDefault,
{ });
break;
}
currentFileSystemInfo = enumerator.Current; return fileSystemInfos
} .Select(CreateDisplayFileInfo);
catch (UnauthorizedAccessException)
{
continue;
}
yield return currentFileSystemInfo;
}
}
} }
private static DisplayFileInfo CreateDisplayFileInfo(FileSystemInfo fileSystemInfo) private static DisplayFileInfo CreateDisplayFileInfo(FileSystemInfo fileSystemInfo)

View File

@@ -36,15 +36,10 @@ namespace Microsoft.Plugin.Folder.Sources
return search.Any(c => SpecialSearchChars.Contains(c)); return search.Any(c => SpecialSearchChars.Contains(c));
} }
public static SearchOption GetSearchOptions(string query) public static bool RecursiveSearch(string query)
{ {
// give the ability to search all folder when it contains a > // give the ability to search all folder when it contains a >
if (query.Any(c => c.Equals('>'))) return query.Any(c => c.Equals('>'));
{
return SearchOption.AllDirectories;
}
return SearchOption.TopDirectoryOnly;
} }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1308:Normalize strings to uppercase", Justification = "Do not want to change the behavior of the application, but want to enforce static analysis")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1308:Normalize strings to uppercase", Justification = "Do not want to change the behavior of the application, but want to enforce static analysis")]
@@ -99,9 +94,9 @@ namespace Microsoft.Plugin.Folder.Sources
} }
var (search, incompleteName) = processed; var (search, incompleteName) = processed;
var searchOption = GetSearchOptions(incompleteName); var isRecursive = RecursiveSearch(incompleteName);
if (searchOption == SearchOption.AllDirectories) if (isRecursive)
{ {
// match everything before and after search term using supported wildcard '*', ie. *searchterm* // match everything before and after search term using supported wildcard '*', ie. *searchterm*
if (string.IsNullOrEmpty(incompleteName)) if (string.IsNullOrEmpty(incompleteName))
@@ -117,7 +112,7 @@ namespace Microsoft.Plugin.Folder.Sources
yield return new CreateOpenCurrentFolderResult(search); yield return new CreateOpenCurrentFolderResult(search);
// Note: Take 1000 is so that you don't search the whole system before you discard // Note: Take 1000 is so that you don't search the whole system before you discard
var lookup = _queryFileSystemInfo.MatchFileSystemInfo(search, incompleteName, searchOption) var lookup = _queryFileSystemInfo.MatchFileSystemInfo(search, incompleteName, isRecursive)
.Take(1000) .Take(1000)
.ToLookup(r => r.Type); .ToLookup(r => r.Type);