-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathFolderManifest.cs
More file actions
66 lines (55 loc) · 1.93 KB
/
FolderManifest.cs
File metadata and controls
66 lines (55 loc) · 1.93 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
54
55
56
57
58
59
60
61
62
63
64
65
66
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
namespace Packrat
{
public class FolderManifest : Dictionary<string, List<string>>
{
// Constructor for JSON deserializer
public FolderManifest()
{
}
// Constructor to use when creating a new manifest
public FolderManifest(string folder)
{
folder = EndWithPathSep(folder);
ComputeHashes(folder);
}
private void ComputeHashes(string folder)
{
var files = Directory.EnumerateFiles(folder, "*.*", SearchOption.AllDirectories);
var groupedHashes = files.AsParallel()
.Select(file => new Tuple<string, string>(HashFile(file), RelativePath(folder, file)))
.GroupBy(t => t.Item1, t => t.Item2);
foreach (var entry in groupedHashes)
{
Add(entry.Key, new List<string>(entry));
}
}
private static string HashFile(string path)
{
var hasher = SHA1.Create();
hasher.Initialize();
using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
{
byte[] hashBytes = hasher.ComputeHash(stream);
return hashBytes.Aggregate("", (s, b) => s + b.ToString("X2"));
}
}
private static string RelativePath(string rootPath, string path)
{
rootPath = EndWithPathSep(rootPath);
if (path.StartsWith(rootPath))
{
return path.Substring(rootPath.Length);
}
return path;
}
private static string EndWithPathSep(string path)
{
return path.EndsWith("\\") ? path : path + "\\";
}
}
}