private void AnalyzeFile(string fileName) { if (CheckCancelled(fileName)) return; DatFileInitParams openParams = new DatFileInitParams(); openParams.FileName = fileName; openParams.IsReadOnly = true; try { using (DatFile file = DatFile.OpenExisting(openParams)) { if (CheckCancelled(fileName)) return; int numFiles = 0; int numFrags = 0; byte hint = 0; ReportStatus(fileName, "Analyzing"); CalculateFragmentation(InternalHandle(file), out numFiles, out numFrags, out hint); if (CheckCancelled(fileName)) return; bool shouldDefrag = ((1 == hint) || ((numFrags - numFiles) > 100)); long count = CalcExternalFrags(Path.Combine(Directory.GetCurrentDirectory(), fileName)); bool shouldExtDefrag = count > externalFragsThreshold; AnalyzeProgress progress = new AnalyzeProgress(shouldDefrag, fileName, numFrags, numFiles, shouldDefrag, count, shouldExtDefrag, "Analyzed"); backgroundWorkerProcessing.ReportProgress(1, progress); } } catch { ReportStatus(fileName, "Unexpected error while analyzing file. May not have permissions to access it."); } }
private void DatDefragFile(string fileName) { backgroundWorkerProcessing.ReportProgress(1, new StatusProgress(fileName, "Starting Internal Defragmentation")); if (!ValidateFreeSpace(fileName)) { return; } if (CheckCancelled(fileName)) return; string defragFileName = string.Concat("defrag_", fileName); if (!CleanupOldTemp(fileName, defragFileName, string.Empty)) return; if (!CleanupOldTemp(fileName, defragFileName, "_aux_1.datx")) return; try { DatFileInitParams initParams = new DatFileInitParams { FileName = fileName, IsReadOnly = true }; try { using (DatFile sourceFile = DatFile.OpenExisting(initParams)) { DatFileInitParams params2 = new DatFileInitParams { FileName = defragFileName, IsReadOnly = false }; int lastPercentComplete = 0; Stopwatch watch = new Stopwatch(); watch.Start(); try { if (CheckCancelled(fileName)) return; using (DatFile destFile = DatFile.CreateNew(params2, sourceFile)) { foreach (Subfile subfile in sourceFile.Subfiles) { if (CheckCancelled(fileName)) return; destFile.AddSubfile(subfile); subfile.Dispose(); int percentComplete = sourceFile.CachedNumSubfiles == destFile.CachedNumSubfiles ? 100 : (int)(100.0 * (double)destFile.CachedSize / (double)sourceFile.CachedSize); if (percentComplete != lastPercentComplete || sourceFile.CachedNumSubfiles == destFile.CachedNumSubfiles) { backgroundWorkerProcessing.ReportProgress(1, new StatusProgress(fileName, string.Format("{0}%, {1:0.00}MB/s", percentComplete, (double)destFile.CachedSize / (double)watch.ElapsedTicks * 10.0))); lastPercentComplete = percentComplete; } } } } catch { backgroundWorkerProcessing.ReportProgress(1, new StatusProgress(fileName, "Unable to create new internally defragmented dat file.")); return; } } } catch { backgroundWorkerProcessing.ReportProgress(1, new StatusProgress(fileName, "Unable to open existing file.")); return; } if (CheckCancelled(fileName)) return; string backupFileName = string.Concat("backup_", fileName); if (!CleanupOldBackup(fileName, backupFileName, string.Empty)) return; if (!CleanupOldBackup(fileName, backupFileName, "_aux_1.datx")) return; SwitchFiles(fileName, defragFileName, backupFileName, string.Empty); } finally { try { if (File.Exists(defragFileName)) { File.Delete(defragFileName); } } catch { backgroundWorkerProcessing.ReportProgress(1, new StatusProgress(fileName, "Unexpected error while cleaning up temporary file left behind due to previous error.")); } } }