Skip to content

Commit b414ad5

Browse files
Add FileSystemFileProvider to expose an IFileSystem as IFileProvider
1 parent 8b2a3f4 commit b414ad5

File tree

4 files changed

+217
-0
lines changed

4 files changed

+217
-0
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using Microsoft.Extensions.FileProviders;
6+
7+
namespace Umbraco.Cms.Core.IO
8+
{
9+
/// <summary>
10+
/// Represents the directory contents in an <see cref="IFileSystem" />.
11+
/// </summary>
12+
/// <seealso cref="Microsoft.Extensions.FileProviders.IDirectoryContents" />
13+
public class FileSystemDirectoryContents : IDirectoryContents
14+
{
15+
private readonly IFileSystem _fileSystem;
16+
private readonly string _subpath;
17+
private IEnumerable<IFileInfo> _entries = null!;
18+
19+
/// <summary>
20+
/// Initializes a new instance of the <see cref="FileSystemDirectoryContents"/> class.
21+
/// </summary>
22+
/// <param name="fileSystem">The file system.</param>
23+
/// <param name="subpath">The subpath.</param>
24+
/// <exception cref="System.ArgumentNullException">
25+
/// fileSystem
26+
/// or
27+
/// subpath
28+
/// </exception>
29+
public FileSystemDirectoryContents(IFileSystem fileSystem, string subpath)
30+
{
31+
_fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
32+
_subpath = subpath ?? throw new ArgumentNullException(nameof(subpath));
33+
}
34+
35+
/// <inheritdoc />
36+
public bool Exists => true;
37+
38+
/// <inheritdoc />
39+
public IEnumerator<IFileInfo> GetEnumerator()
40+
{
41+
EnsureInitialized();
42+
return _entries.GetEnumerator();
43+
}
44+
45+
/// <inheritdoc />
46+
IEnumerator IEnumerable.GetEnumerator()
47+
{
48+
EnsureInitialized();
49+
return _entries.GetEnumerator();
50+
}
51+
52+
private void EnsureInitialized()
53+
{
54+
_entries = _fileSystem.GetDirectories(_subpath).Select<string, IFileInfo>(d => new FileSystemDirectoryInfo(_fileSystem, d))
55+
.Union(_fileSystem.GetFiles(_subpath).Select<string, IFileInfo>(f => new FileSystemFileInfo(_fileSystem, f)))
56+
.ToList();
57+
}
58+
}
59+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System;
2+
using System.IO;
3+
using Microsoft.Extensions.FileProviders;
4+
5+
namespace Umbraco.Cms.Core.IO
6+
{
7+
/// <summary>
8+
/// Represents a directory in an <see cref="IFileSystem" />.
9+
/// </summary>
10+
/// <seealso cref="Microsoft.Extensions.FileProviders.IFileInfo" />
11+
public class FileSystemDirectoryInfo : IFileInfo
12+
{
13+
private readonly IFileSystem _fileSystem;
14+
private readonly string _subpath;
15+
16+
/// <summary>
17+
/// Initializes a new instance of the <see cref="FileSystemDirectoryInfo" /> class.
18+
/// </summary>
19+
/// <param name="fileSystem">The file system.</param>
20+
/// <param name="subpath">The subpath.</param>
21+
public FileSystemDirectoryInfo(IFileSystem fileSystem, string subpath)
22+
{
23+
_fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
24+
_subpath = subpath ?? throw new ArgumentNullException(nameof(subpath));
25+
}
26+
27+
/// <inheritdoc />
28+
public bool Exists => true;
29+
30+
/// <inheritdoc />
31+
public bool IsDirectory => true;
32+
33+
/// <inheritdoc />
34+
public DateTimeOffset LastModified => _fileSystem.GetLastModified(_subpath);
35+
36+
/// <inheritdoc />
37+
public long Length => -1;
38+
39+
/// <inheritdoc />
40+
public string Name => _fileSystem.GetRelativePath(_subpath);
41+
42+
/// <inheritdoc />
43+
public string PhysicalPath => null!;
44+
45+
/// <inheritdoc />
46+
public Stream CreateReadStream() => throw new InvalidOperationException("Cannot create a stream for a directory.");
47+
}
48+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System;
2+
using System.IO;
3+
using Microsoft.Extensions.FileProviders;
4+
5+
namespace Umbraco.Cms.Core.IO
6+
{
7+
/// <summary>
8+
/// Represents a file in an <see cref="IFileSystem" />.
9+
/// </summary>
10+
/// <seealso cref="Microsoft.Extensions.FileProviders.IFileInfo" />
11+
public class FileSystemFileInfo : IFileInfo
12+
{
13+
private readonly IFileSystem _fileSystem;
14+
private readonly string _subpath;
15+
16+
/// <summary>
17+
/// Initializes a new instance of the <see cref="FileSystemFileInfo" /> class.
18+
/// </summary>
19+
/// <param name="fileSystem">The file system.</param>
20+
/// <param name="subpath">The subpath.</param>
21+
public FileSystemFileInfo(IFileSystem fileSystem, string subpath)
22+
{
23+
_fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
24+
_subpath = subpath ?? throw new ArgumentNullException(nameof(subpath));
25+
}
26+
27+
/// <inheritdoc />
28+
public bool Exists => true;
29+
30+
/// <inheritdoc />
31+
public bool IsDirectory => false;
32+
33+
/// <inheritdoc />
34+
public DateTimeOffset LastModified => _fileSystem.GetLastModified(_subpath);
35+
36+
/// <inheritdoc />
37+
public long Length => _fileSystem.GetSize(_subpath);
38+
39+
/// <inheritdoc />
40+
public string Name => _fileSystem.GetRelativePath(_subpath);
41+
42+
/// <inheritdoc />
43+
public string PhysicalPath => null!;
44+
45+
/// <inheritdoc />
46+
public Stream CreateReadStream() => _fileSystem.OpenFile(_subpath);
47+
}
48+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
using System;
2+
using Microsoft.Extensions.FileProviders;
3+
using Microsoft.Extensions.Primitives;
4+
5+
namespace Umbraco.Cms.Core.IO
6+
{
7+
/// <summary>
8+
/// Exposes an <see cref="IFileSystem" /> as an <see cref="IFileProvider" />.
9+
/// </summary>
10+
/// <seealso cref="Microsoft.Extensions.FileProviders.IFileProvider" />
11+
public class FileSystemFileProvider : IFileProvider
12+
{
13+
/// <summary>
14+
/// Initializes a new instance of the <see cref="FileSystemFileProvider" /> class.
15+
/// </summary>
16+
/// <param name="fileSystem">The file system.</param>
17+
/// <param name="pathPrefix">The path prefix.</param>
18+
/// <exception cref="System.ArgumentNullException">fileSystem</exception>
19+
public FileSystemFileProvider(IFileSystem fileSystem, string pathPrefix = null)
20+
{
21+
FileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
22+
PathPrefix = pathPrefix;
23+
}
24+
25+
/// <summary>
26+
/// Gets the file system.
27+
/// </summary>
28+
protected IFileSystem FileSystem { get; }
29+
30+
/// <summary>
31+
/// Gets the path prefix.
32+
/// </summary>
33+
protected string PathPrefix { get; }
34+
35+
/// <inheritdoc />
36+
public IDirectoryContents GetDirectoryContents(string subpath)
37+
{
38+
var path = PathPrefix + subpath;
39+
if (path == null || !FileSystem.DirectoryExists(path))
40+
{
41+
return NotFoundDirectoryContents.Singleton;
42+
}
43+
44+
return new FileSystemDirectoryContents(FileSystem, path);
45+
}
46+
47+
/// <inheritdoc />
48+
public IFileInfo GetFileInfo(string subpath)
49+
{
50+
var path = PathPrefix + subpath;
51+
if (path == null || !FileSystem.FileExists(path))
52+
{
53+
return new NotFoundFileInfo(path);
54+
}
55+
56+
return new FileSystemFileInfo(FileSystem, path);
57+
}
58+
59+
/// <inheritdoc />
60+
public IChangeToken Watch(string filter) => NullChangeToken.Singleton;
61+
}
62+
}

0 commit comments

Comments
 (0)