예제 #1
0
        public override void LoadFromDisk()
        {
            status.stopwatch.Reset();
            status.stopwatch.Start();
            status.UpdateProgress(0f);
            log.Info("Loading unpacked bigfile from disk...");

            UnpackedFileKeyMappingFile mappingFile = new UnpackedFileKeyMappingFile(new DirectoryInfo(fileOrDirectory));

            renamedMapping = mappingFile.LoadMappingData();

            status.UpdateProgress(0.2f);

            SegmentHeader = segment.ReadSegmentHeader();
            FileHeader    = header.ReadHeader(ref SegmentHeader);

            log.Info(string.Format("Count info offset: {0:X8}", SegmentHeader.InfoOffset));
            version = BigFileVersions.GetVersion(FileHeader.BigFileVersion);
            fileUtil.BigFileVersion = version;
            filesAndFolders.Version = version;
            log.Info(string.Format("Version: {0:X4}", FileHeader.BigFileVersion));

            rawFolderInfos = filesAndFolders.ReadFolderInfos(ref SegmentHeader, ref FileHeader);
            rawFileInfos   = filesAndFolders.ReadFileInfos(ref SegmentHeader, ref FileHeader);

            fileUtil.BigFileVersion = version;
            filesAndFolders.Version = version;

            status.UpdateProgress(0.4f);

            rootFolder = fileUtil.CreateRootFolderTree(rawFolderInfos);
            fileMap    = fileUtil.CreateFileMappingData(rootFolder, rawFileInfos);
            fileUtil.MapFilesToFolders(rootFolder, fileMap);

            UnpackedFolderMapAndFilesList folderAndFiles = fileUtil.CreateFolderTreeAndFilesListFromDirectory(new DirectoryInfo(directory.FullName + "\\" + BigFileConst.UNPACK_DIR), renamedMapping, fileMap);

            rootFolder = folderAndFiles.folderMap[0];

            rawFileInfos   = folderAndFiles.filesList;
            rawFolderInfos = folderAndFiles.foldersList;

            status.UpdateProgress(0.6f);

            fileMap = fileUtil.CreateFileMappingData(folderAndFiles.folderMap[0], folderAndFiles.filesList);

            status.UpdateProgress(0.8f);

            fileUtil.MapFilesToFolders(rootFolder, fileMap);

            status.UpdateProgress(1.0f);

            status.stopwatch.Stop();
            log.Info("Unpacked bigfile loaded!");
            log.Info("  Time taken: " + status.TimeTaken + "ms");
        }
예제 #2
0
        public BigFileUnpackOperationStatus UnpackBigfile(BigFileUnpackOptions options)
        {
            if (options.Threads > MAX_UNPACK_THREADS)
            {
                log.Error(string.Format("Can't have more threads than the max! ({0} > {1})", options.Threads, MAX_UNPACK_THREADS));
                log.Error("    Threads will be clamped to the max!");
                options.Threads = MAX_UNPACK_THREADS;
            }

            log.Info("Unpacking a bigfile to directory: \"" + options.Directory.FullName + "\"");

            options.Log(log);

            if (!options.Directory.Exists)
            {
                log.Info("Directory does not exist, creating it...");
                Directory.CreateDirectory(options.Directory.FullName);
            }

            GenerateYetiMetadataFile(options.Directory, bigFile);

            DirectoryInfo unpackDir = new DirectoryInfo(options.Directory.FullName + "\\" + BigFileConst.UNPACK_DIR);

            log.Info("Creating unpack dir: " + unpackDir.FullName);
            Directory.CreateDirectory(unpackDir.FullName);

            log.Info("Creating unpacked directories...");
            CreateDirectoriesFromTree(unpackDir, bigFile.RootFolder);

            log.Info("Creating renamed mapping file...");
            UnpackedRenamedFileMapping renamedMapping = CreateRenamedFileMapping(bigFile.RootFolder);
            UnpackedFileKeyMappingFile mappingFile    = new UnpackedFileKeyMappingFile(options.Directory);

            mappingFile.SaveMappingData(renamedMapping);
            log.Info("Mapping file saved!");

            stopwatch.Reset();
            stopwatch.Start();

            log.Info("Beginning extract...");

            verifyAndResetThreads(options.Threads);

            if ((options.Flags & BigFileFlags.UseThreading) != 0)
            {
                int dividedCount     = bigFile.FileMap.FilesList.Length / options.Threads;
                int dividedRemainder = bigFile.FileMap.FilesList.Length % options.Threads;
                log.Info("Divided files into " + options.Threads + " pools of " + dividedCount + " with " + dividedRemainder + " left over (to be tacked onto the last!)");

                List <UnpackThreadInfo> usingThreads = new List <UnpackThreadInfo>();
                for (int i = 0; i < options.Threads; i++)
                {
                    unpackThreads[i].options            = options;
                    unpackThreads[i].bigFile            = bigFile;
                    unpackThreads[i].fileMapping        = renamedMapping;
                    unpackThreads[i].startIndex         = i * dividedCount;
                    unpackThreads[i].count              = dividedCount;
                    unpackThreads[i].threadID           = i;
                    unpackThreads[i].OnWorkDoneCallback = internal_OnThreadFinished;
                }
                unpackThreads[options.Threads - 1].count += dividedRemainder; //add the remainder onto the last info

                for (int i = 0; i < options.Threads; i++)
                {
                    ThreadPool.QueueUserWorkItem(internal_UnpackFiles, unpackThreads[i]);
                    usingThreads.Add(unpackThreads[i]);
                }

                return(new BigFileUnpackOperationStatus(usingThreads));
            }
            else //use the function for threads even without one
            {
                unpackThreads[0].options            = options;
                unpackThreads[0].bigFile            = bigFile;
                unpackThreads[0].fileMapping        = renamedMapping;
                unpackThreads[0].startIndex         = 0;
                unpackThreads[0].count              = bigFile.FileMap.FilesList.Length;
                unpackThreads[0].threadID           = 0;
                unpackThreads[0].OnWorkDoneCallback = internal_OnThreadFinished;

                internal_UnpackFiles(unpackThreads[0]); //teehee

                diagData.WriteUnpackedFiles = stopwatch.ElapsedMilliseconds;
                stopwatch.Stop();

                log.Info("Extract complete!");

                diagData.DebugLog(log);

                log.Info("Unpack complete!");

                return(null);
            }
        }