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