-
Notifications
You must be signed in to change notification settings - Fork 74
Expand file tree
/
Copy pathFileTreeSnapshot.cs
More file actions
53 lines (46 loc) · 1.88 KB
/
Copy pathFileTreeSnapshot.cs
File metadata and controls
53 lines (46 loc) · 1.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
using System;
using System.Collections.Generic;
using System.Linq;
namespace GeneralUpdate.Core.FileSystem;
/// <summary>
/// Immutable snapshot of a file entry in a directory tree.
/// Captures path, size, and modification timestamp for comparison.
/// </summary>
public readonly record struct FileEntry(
string RelativePath,
long Size,
DateTime LastWriteTimeUtc
);
/// <summary>
/// Immutable snapshot of a directory tree at a point in time.
/// Created by <see cref="FileTreeEnumerator"/> + <see cref="IBlackListMatcher"/>.
/// </summary>
public sealed class FileTreeSnapshot
{
public DateTime CreatedAt { get; } = DateTime.UtcNow;
public string RootPath { get; }
public IReadOnlyList<FileEntry> Entries { get; }
public FileTreeSnapshot(string rootPath, IEnumerable<FileEntry> entries)
{
RootPath = rootPath ?? throw new ArgumentNullException(nameof(rootPath));
Entries = (entries ?? Array.Empty<FileEntry>()).ToList();
}
public static FileTreeSnapshot FromEnumerator(string rootPath, FileTreeEnumerator enumerator)
{
var entries = new List<FileEntry>();
var normalizedRoot = rootPath.EndsWith(System.IO.Path.DirectorySeparatorChar.ToString())
? rootPath
: rootPath + System.IO.Path.DirectorySeparatorChar;
foreach (var filePath in enumerator.EnumerateFiles(rootPath))
{
var fi = new System.IO.FileInfo(filePath);
// Manual relative path (netstandard2.0 compatible)
var relative = filePath.StartsWith(normalizedRoot)
? filePath.Substring(normalizedRoot.Length)
: filePath;
entries.Add(new FileEntry(relative, fi.Length, fi.LastWriteTimeUtc));
}
return new FileTreeSnapshot(rootPath, entries);
}
public static FileTreeSnapshot Empty(string rootPath) => new(rootPath, Array.Empty<FileEntry>());
}