diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/ref/Microsoft.Extensions.FileProviders.Physical.cs b/src/libraries/Microsoft.Extensions.FileProviders.Physical/ref/Microsoft.Extensions.FileProviders.Physical.cs
index 658a47bbeb6f56..827e092eb7e704 100644
--- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/ref/Microsoft.Extensions.FileProviders.Physical.cs
+++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/ref/Microsoft.Extensions.FileProviders.Physical.cs
@@ -34,6 +34,18 @@ public PhysicalDirectoryContents(string directory, Microsoft.Extensions.FileProv
}
namespace Microsoft.Extensions.FileProviders.Physical
{
+ public partial class ExcludedFileInfo : Microsoft.Extensions.FileProviders.IFileInfo
+ {
+ public ExcludedFileInfo(System.IO.FileInfo info, ExclusionFilters matchingFilter) { }
+ public Microsoft.Extensions.FileProviders.Physical.ExclusionFilters MatchingFilter { get { throw null; } }
+ public bool Exists { get { throw null; } }
+ public bool IsDirectory { get { throw null; } }
+ public System.DateTimeOffset LastModified { get { throw null; } }
+ public long Length { get { throw null; } }
+ public string Name { get { throw null; } }
+ public string PhysicalPath { get { throw null; } }
+ public System.IO.Stream CreateReadStream() { throw null; }
+ }
[System.FlagsAttribute]
public enum ExclusionFilters
{
@@ -43,6 +55,11 @@ public enum ExclusionFilters
System = 4,
Sensitive = 7,
}
+ public partial class FileExcludedException : System.Exception
+ {
+ public FileExcludedException(string message, ExclusionFilters matchingFilter) { }
+ public Microsoft.Extensions.FileProviders.Physical.ExclusionFilters MatchingFilter { get { throw null; } }
+ }
public partial class PhysicalDirectoryInfo : Microsoft.Extensions.FileProviders.IFileInfo
{
public PhysicalDirectoryInfo(System.IO.DirectoryInfo info) { }
diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/ExcludedFileInfo.cs b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/ExcludedFileInfo.cs
new file mode 100644
index 00000000000000..eaf944c2e44c68
--- /dev/null
+++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/ExcludedFileInfo.cs
@@ -0,0 +1,59 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.IO;
+
+namespace Microsoft.Extensions.FileProviders.Physical
+{
+ public class ExcludedFileInfo : IFileInfo
+ {
+ private readonly FileInfo _info;
+
+ ///
+ /// Initializes an instance of .
+ ///
+ /// The of the file that could was excluded.
+ /// The the file matched with.
+ public ExcludedFileInfo(FileInfo info, ExclusionFilters matchingFilter)
+ {
+ _info = info;
+ MatchingFilter = matchingFilter;
+ }
+
+ ///
+ /// The the file matched with.
+ ///
+ public ExclusionFilters MatchingFilter { get; }
+
+ ///
+ public bool Exists => _info.Exists;
+
+ ///
+ public long Length => _info.Length;
+
+ ///
+ public string PhysicalPath => _info.FullName;
+
+ ///
+ public string Name => _info.Name;
+
+ ///
+ public DateTimeOffset LastModified => _info.LastWriteTimeUtc;
+
+ ///
+ /// Always false.
+ ///
+ public bool IsDirectory => false;
+
+ ///
+ /// Always throws. A stream cannot be created for non-existing file.
+ ///
+ /// Always thrown.
+ /// Does not return
+ public Stream CreateReadStream()
+ {
+ throw new FileExcludedException(SR.Format(SR.FileExcluded, Name), MatchingFilter);
+ }
+ }
+}
diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/FileExcludedException.cs b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/FileExcludedException.cs
new file mode 100644
index 00000000000000..022c7fa81bf8cb
--- /dev/null
+++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/FileExcludedException.cs
@@ -0,0 +1,18 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+
+namespace Microsoft.Extensions.FileProviders.Physical
+{
+ public class FileExcludedException : Exception
+ {
+ public ExclusionFilters MatchingFilter { get; }
+
+ public FileExcludedException(string message, ExclusionFilters matchingFilter)
+ : base(message)
+ {
+ MatchingFilter = matchingFilter;
+ }
+ }
+}
diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/FileSystemInfoHelper.cs b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/FileSystemInfoHelper.cs
index 067a1545860e2a..a267d5c5f2ab57 100644
--- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/FileSystemInfoHelper.cs
+++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Internal/FileSystemInfoHelper.cs
@@ -8,24 +8,37 @@ namespace Microsoft.Extensions.FileProviders.Physical
{
internal static class FileSystemInfoHelper
{
- public static bool IsExcluded(FileSystemInfo fileSystemInfo, ExclusionFilters filters)
+ public static bool IsExcluded(FileSystemInfo fileSystemInfo, ExclusionFilters filters) =>
+ FindMatchingExclusionFilter(fileSystemInfo, filters) != ExclusionFilters.None;
+
+ public static ExclusionFilters FindMatchingExclusionFilter(FileSystemInfo fileSystemInfo, ExclusionFilters filters)
{
if (filters == ExclusionFilters.None)
{
- return false;
+ return ExclusionFilters.None;
}
- else if (fileSystemInfo.Name.StartsWith(".", StringComparison.Ordinal) && (filters & ExclusionFilters.DotPrefixed) != 0)
+
+ if (fileSystemInfo.Name.StartsWith(".", StringComparison.Ordinal) && (filters & ExclusionFilters.DotPrefixed) != 0)
{
- return true;
+ return ExclusionFilters.DotPrefixed;
}
- else if (fileSystemInfo.Exists &&
- (((fileSystemInfo.Attributes & FileAttributes.Hidden) != 0 && (filters & ExclusionFilters.Hidden) != 0) ||
- ((fileSystemInfo.Attributes & FileAttributes.System) != 0 && (filters & ExclusionFilters.System) != 0)))
+
+ if (fileSystemInfo.Exists)
{
- return true;
+ if ((fileSystemInfo.Attributes & FileAttributes.Hidden) != 0 &&
+ (filters & ExclusionFilters.Hidden) != 0)
+ {
+ return ExclusionFilters.Hidden;
+ }
+
+ if ((fileSystemInfo.Attributes & FileAttributes.System) != 0 &&
+ (filters & ExclusionFilters.System) != 0)
+ {
+ return ExclusionFilters.System;
+ }
}
- return false;
+ return ExclusionFilters.None;
}
}
}
diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs
index 4238fff652eb7a..16caa1910288b5 100644
--- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs
+++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/PhysicalFileProvider.cs
@@ -266,9 +266,10 @@ public IFileInfo GetFileInfo(string subpath)
}
var fileInfo = new FileInfo(fullPath);
- if (FileSystemInfoHelper.IsExcluded(fileInfo, _filters))
+ var matchingExclusion = FileSystemInfoHelper.FindMatchingExclusionFilter(fileInfo, _filters);
+ if (matchingExclusion != ExclusionFilters.None)
{
- return new NotFoundFileInfo(subpath);
+ return new ExcludedFileInfo(fileInfo, matchingExclusion);
}
return new PhysicalFileInfo(fileInfo);
diff --git a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Resources/Strings.resx b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Resources/Strings.resx
index 4d234ccabe2024..20c369aa5ba0a7 100644
--- a/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Resources/Strings.resx
+++ b/src/libraries/Microsoft.Extensions.FileProviders.Physical/src/Resources/Strings.resx
@@ -129,4 +129,7 @@
Unexpected type of FileSystemInfo
+
+ The file {0} has been excluded.
+
\ No newline at end of file