public static string GetDirectoryHash(string directory, params string[] fileGlobPatterns) { ControlFlow.Assert(Directory.Exists(directory), $"Directory.Exists({directory})"); var files = (fileGlobPatterns.Length == 0 ? Directory.GetFiles(directory, "*", SearchOption.AllDirectories) : PathConstruction.GlobFiles(directory, fileGlobPatterns)) .OrderBy(x => x).ToList(); using (var md5 = MD5.Create()) { foreach (var file in files) { var relativePath = PathConstruction.GetRelativePath(directory, file); var unixNormalizedPath = PathConstruction.NormalizePath(relativePath, separator: '/'); var pathBytes = Encoding.UTF8.GetBytes(unixNormalizedPath); md5.TransformBlock(pathBytes, inputOffset: 0, inputCount: pathBytes.Length, outputBuffer: pathBytes, outputOffset: 0); var contentBytes = File.ReadAllBytes(file); md5.TransformBlock(contentBytes, inputOffset: 0, inputCount: contentBytes.Length, outputBuffer: contentBytes, outputOffset: 0); } md5.TransformFinalBlock(new byte[0], inputOffset: 0, inputCount: 0); return(BitConverter.ToString(md5.Hash).Replace("-", "").ToLower()); } }
private static void CompressTar( string directory, string archiveFile, Predicate <FileInfo> filter, FileMode fileMode, Func <Stream, Stream> outputStreamFactory) { Log.Information("Compressing content of {Directory} to {File} ...", directory, Path.GetFileName(archiveFile)); FileSystemTasks.EnsureExistingParentDirectory(archiveFile); var files = GetFiles(directory, filter); using var fileStream = File.Open(archiveFile, fileMode, FileAccess.ReadWrite); using var outputStream = outputStreamFactory(fileStream); using var tarArchive = TarArchive.CreateOutputTarArchive(outputStream); foreach (var file in files) { var entry = TarEntry.CreateEntryFromFile(file); var relativePath = PathConstruction.GetRelativePath(directory, file); entry.Name = PathConstruction.NormalizePath(relativePath, separator: '/'); tarArchive.WriteEntry(entry, recurse: false); } }