public static void TraverseTreePostorder(DirectoryTreeNode root, Action <DirectoryTreeNode> directoryAction, Action <FileRecord> fileAction) { foreach (DirectoryTreeNode current in root.Children) { DirectoryTreeNode.TraverseTreePostorder(current, directoryAction, fileAction); if (directoryAction != null) { directoryAction(current); } } if (fileAction != null) { foreach (FileRecord current2 in root.Files) { fileAction(current2); } } }
public void Save(string pathToGgpkNew, Action <string> output) { if (output != null) { output("Saving GGPK..." + Environment.NewLine); } FileStream readStream; FileStream writeStream; using (readStream = File.OpenRead(_pathToGppk)) using (writeStream = File.OpenWrite(pathToGgpkNew)) { var reader = new BinaryReader(readStream); var writer = new BinaryWriter(writeStream); var ggpkRecord = RecordOffsets[0] as GgpkRecord; if (ggpkRecord == null) { throw new Exception("First record isn't GGPK record"); } // Skip GGPK record for now writer.Seek((int)ggpkRecord.Length, SeekOrigin.Begin); // recursively write files and folders records var changedOffsets = new Dictionary <long, long>(); var previousPercentComplete = 0.0; var fileCopied = 0.0; DirectoryTreeNode.TraverseTreePostorder( DirectoryRoot, dir => dir.Record.Write(writer, changedOffsets), file => { var data = file.ReadFileContent(reader); file.Write(writer, changedOffsets); writer.Write(data); fileCopied++; var percentComplete = fileCopied / _files.Count; if (!(percentComplete - previousPercentComplete >= 0.05f)) { return; } if (output != null) { output(String.Format(" {0:00.00}%", 100.0 * percentComplete)); } previousPercentComplete = percentComplete; }); if (output != null) { output(" 100%"); } // write root directory var rootDirectoryOffset = writer.BaseStream.Position; DirectoryRoot.Record.Write(writer, changedOffsets); // write single Free record var firstFreeRecordOffset = writer.BaseStream.Position; var freeRecord = new FreeRecord(16, firstFreeRecordOffset, 0); freeRecord.Write(writer, null); // write GGPK record writer.Seek(0, SeekOrigin.Begin); var ggpkRecordNew = new GgpkRecord(ggpkRecord.Length); ggpkRecordNew.RecordOffsets[0] = rootDirectoryOffset; ggpkRecordNew.RecordOffsets[1] = firstFreeRecordOffset; ggpkRecordNew.Write(writer, changedOffsets); if (output != null) { output("Finished !!!"); } } }