1 module filenode; 2 import std.array; 3 import std.file; 4 import std.stdio; 5 import std.algorithm; 6 7 struct FileNode { 8 string name; 9 ulong weight; 10 FileNode[] children; 11 bool invalid; 12 this(string name) { 13 this.name = name; 14 this.invalid = true; 15 } 16 this(string name, ulong weight) { 17 this(name, weight, null); 18 } 19 this(string name, ulong weight, FileNode[] childs) { 20 this.name = name; 21 this.weight = weight; 22 this.children = childs; 23 } 24 FileNode[] childs() { 25 return children; 26 } 27 ulong getWeight() { 28 return weight; 29 } 30 string getName() { 31 return name; 32 } 33 string toString() { 34 import std.conv; 35 return "{ name: \"" ~getName() ~ "\" , weight: " ~ getWeight().to!string ~ " }"; 36 } 37 } 38 39 FileNode calcFileNode(DirEntry entry) { 40 if (entry.isDir) { 41 auto childs = dirEntries(entry.name, SpanMode.shallow, false) 42 .map!(v => calcFileNode(v)) 43 .filter!(v => !v.invalid).array() 44 .sort!((a, b) => a.getWeight() > b.getWeight()).array(); 45 auto childSize = 0L.reduce!((sum, v) => sum + v.getWeight)(childs); 46 return FileNode(entry, childSize, childs); 47 } else { 48 try { 49 size_t s = DirEntry(entry).size; 50 return FileNode(entry, s); 51 } catch (Exception e) { 52 writeln("problems with file", entry); 53 return FileNode(entry); 54 } 55 } 56 } 57 58 size_t calcSize(DirEntry entry) { 59 if (entry.isDir) { 60 size_t res = 0; 61 foreach (DirEntry e; dirEntries(entry.name, SpanMode.shallow, false)) { 62 res += calcSize(e); 63 } 64 return res; 65 } else { 66 size_t res = 0; 67 try { 68 res = entry.size; 69 } catch (Exception e) { 70 } 71 return res; 72 } 73 } 74 75 size_t calcSize(string file) { 76 return calcSize(DirEntry(file)); 77 }