public static Node Generate(System.IO.FileInfo fileInfo) { ZipFile file = new ZipFile(fileInfo.FullName); Node node = new Node(); IDictionary<string, IList<Entry>> waiting = new Dictionary<string, IList<Entry>>(); foreach (ZipEntry zipEntry in file) { Entry entry = ParseEntry(zipEntry, node); if (entry != null) { string name = zipEntry.Name.TrimEnd('/'); string path = name.Substring(0, name.LastIndexOf('/')); if (!waiting.ContainsKey(path)) waiting[path] = new List<Entry>(); waiting[path].Add(entry); } if (zipEntry.IsDirectory && waiting.ContainsKey(zipEntry.Name.TrimEnd('/'))) { Node dir = GetDirectory(zipEntry.Name.TrimEnd('/'), node); if (dir != null) { foreach (var dirEntry in waiting[zipEntry.Name.TrimEnd('/')]) { dir.Nodes.Add(dirEntry); } waiting.Remove(zipEntry.Name.TrimEnd('/')); } } } FinalizeEntries(node, waiting, fileInfo); return node; }
public static Node Generate(System.IO.DirectoryInfo directory, bool recursive) { Node node = new Node(); foreach (var subdirectory in directory.EnumerateDirectories()) { Entry dirEntry = new Entry(subdirectory); node.Nodes.Add(dirEntry); if (recursive) { dirEntry.Node = Generate(subdirectory, recursive); dirEntry.UpdateSize(); } } foreach (var file in directory.EnumerateFiles()) { Entry fileEntry = new Entry(file, IsZipFile(file)); node.Nodes.Add(fileEntry); if ((fileEntry.Kind == EntryKind.ZipFile) && recursive) { fileEntry.Node = ZipFileGenerator.Generate(file); fileEntry.UpdateSize(); } } return node; }
internal static int GetEntriesCount(Node node, EntryKind[] kinds) { int count = 0; foreach (var entry in node.Nodes) { foreach (var kind in kinds) { if (entry.Kind == kind) { count++; break; } } } return count; }
public static void Update(System.IO.DirectoryInfo directory, Node node) { IDictionary<string, Entry> entries = new Dictionary<string, Entry>(node.Nodes.Count); foreach (var entry in node.Nodes) { entries.Add(entry.Name, entry); } foreach (var subdirectory in directory.EnumerateDirectories()) { if (entries.ContainsKey(subdirectory.Name)) { entries.Remove(subdirectory.Name); } else { Entry dirEntry = new Entry(subdirectory); node.Nodes.Add(dirEntry); } } foreach (var file in directory.EnumerateFiles()) { if (entries.ContainsKey(file.Name)) { Entry fileEntry = entries[file.Name]; entries.Remove(file.Name); if (fileEntry.LastWriteTime < file.LastWriteTime) { node.Nodes.Remove(fileEntry); node.Nodes.Add(new Entry(file, IsZipFile(file))); } } else { node.Nodes.Add(new Entry(file, IsZipFile(file))); } } foreach (var entryPair in entries) { node.Nodes.Remove(entryPair.Value); } }
private static void FinalizeEntries(Node node, IDictionary<string, IList<Entry>> waiting, System.IO.FileInfo fileInfo) { int lastCount = 0; int count = 0; do { lastCount = count; count = 0; foreach (var waitingInfo in waiting.ToArray()) { Node dir = GetDirectory(waitingInfo.Key, node); if ((dir == null)) { dir = GetDirectory(waitingInfo.Key.Substring(0, Math.Max(0, waitingInfo.Key.LastIndexOf('/'))), node); if (dir != null) { Entry dirEntry = Entry.CreateZipDirectoryEntry(waitingInfo.Key.Substring(waitingInfo.Key.LastIndexOf('/') + 1), fileInfo.LastWriteTime); dirEntry.Node = new Node(); dir.Nodes.Add(dirEntry); dir = dirEntry.Node; } } if (dir != null) { foreach (var dirEntry in waitingInfo.Value) { dir.Nodes.Add(dirEntry); } waiting.Remove(waitingInfo.Key); } else { count += waitingInfo.Value.Count; } } } while ((count > 0) && (lastCount != count)); }
public static Entry SearchEntry(string path, Node parent) { return SearchEntry(path, parent, null, null); }
private void InitRoot() { System.IO.DirectoryInfo root = new System.IO.DirectoryInfo(rootPath); rootNode = DirectoryGenerator.Generate(root, false); lastWriteTime = root.LastWriteTime; }
private static Entry SearchEntry(string path, Node parent, string rootPath, EntryKind? stopAt) { Entry result = null; string[] pathComponents = path.Split(System.IO.Path.DirectorySeparatorChar); Node currentNode = parent; for (int i = 0; i < pathComponents.Length; i++) { result = null; foreach (var entry in currentNode.Nodes) { if (entry.Name == pathComponents[i]) { result = entry; break; } } if (result == null) { break; } if (((result.Kind == EntryKind.File) || (result.Kind == EntryKind.ZipFileEntry)) && (i + 1 < pathComponents.Length)) { throw new System.IO.DirectoryNotFoundException(); } if (result.Node == null) { if (rootPath == null) { throw new System.IO.IOException(); } string elementPath = System.IO.Path.Combine(rootPath, string.Join(new string(System.IO.Path.DirectorySeparatorChar, 1), pathComponents, 0, i + 1)); if (result.Kind == EntryKind.Directory) { result.Node = DirectoryGenerator.Generate(new System.IO.DirectoryInfo(elementPath), false); result.UpdateSize(); } if (result.Kind == EntryKind.ZipFile) { result.Node = ZipFileGenerator.Generate(new System.IO.FileInfo(elementPath)); result.UpdateSize(); } } else if (rootPath != null) { string elementPath = System.IO.Path.Combine(rootPath, string.Join(new string(System.IO.Path.DirectorySeparatorChar, 1), pathComponents, 0, i + 1)); if (result.Kind == EntryKind.Directory) { if (result.LastWriteTime < System.IO.Directory.GetLastWriteTime(elementPath)) { System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(elementPath); DirectoryGenerator.Update(di, result.Node); Entry newEntry = new Entry(di); newEntry.Node = result.Node; newEntry.UpdateSize(); currentNode.Nodes.Remove(result); currentNode.Nodes.Add(newEntry); result = newEntry; } } if (result.Kind == EntryKind.File) { if (result.LastWriteTime < System.IO.File.GetLastWriteTime(elementPath)) { System.IO.FileInfo fi = new System.IO.FileInfo(elementPath); Entry newEntry = new Entry(fi, false); currentNode.Nodes.Remove(result); currentNode.Nodes.Add(newEntry); result = newEntry; } } } if (stopAt.HasValue && (result.Kind == stopAt.Value)) break; currentNode = result.Node; } if ((result != null) && stopAt.HasValue && (result.Kind != stopAt.Value)) return null; return result; }
private static void UpdateSizes(Node node) { foreach (var entry in node.Nodes) { if (entry.Kind == EntryKind.ZipDirectoryEntry) { entry.UpdateSize(); UpdateSizes(entry.Node); } } }
private static Entry ParseEntry(ICSharpCode.SharpZipLib.Zip.ZipEntry entry, Node root) { if ((!entry.IsFile) && (!entry.IsDirectory)) return null; string name = entry.Name.TrimEnd('/'); Node dir = GetDirectory(name.Substring(0, Math.Max(0, name.LastIndexOf('/'))), root); Entry newEntry = new Entry(entry); if (newEntry.Kind == EntryKind.ZipDirectoryEntry) newEntry.Node = new Node(); if (dir == null) return newEntry; dir.Nodes.Add(newEntry); return null; }
private static Node GetDirectory(string path, Node root) { if (path == string.Empty) return root; string[] pathComponents = path.Split('/'); for (int i = 0; i < pathComponents.Length; i++) { bool found = false; foreach (var entry in root.Nodes) { if (entry.Name == pathComponents[0]) { found = true; if (entry.Kind != EntryKind.ZipDirectoryEntry) return null; root = entry.Node; } } if (!found) return null; } return root; }
internal DirectoryEntries(Node node, DateTime writeTime) { this.node = node; this.writeTime = writeTime; }