示例#1
0
 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 !!!");
                    }
                }
        }