/// <summary> /// 指定ディレクトリ以下にあるファイルのリストを作成する /// </summary> /// <param name="rootDir">ルートディレクトリパス</param> /// <returns>ファイルリスト(UFileInfo)</returns> public List <UFileInfo> GetFilesInfo(string rootDir, IProgress <MyProgress> p) { //"C:\test"以下の".txt"ファイルをすべて取得する DirectoryInfo di = new System.IO.DirectoryInfo(rootDir); FileInfo[] files = di.GetFiles("*.*", System.IO.SearchOption.AllDirectories); var myProgress = new MyProgress("GetFilesInfo", 0); int processCnt = 0; List <UFileInfo> list = new List <UFileInfo>(); p.Report(myProgress); foreach (FileInfo f in files) { if (cancelFlag) { throw new Exception("キャンセルされました"); } string fileName = Path.GetFileName(f.FullName); string filePath = Path.GetDirectoryName(f.FullName).Replace(rootDir, ""); UFileInfo ufi = new UFileInfo(fileName, filePath, f.Length, f.LastWriteTime, getFileMD5(f.FullName)); list.Add(ufi); processCnt++; myProgress.Progress = (int)((float)processCnt / (float)files.Length * 100.0f); p.Report(myProgress); } return(list); }
/// <summary> /// 同じかどうかをチェックする /// </summary> /// <param name="ufi"></param> /// <returns>false:異なる / true:同じ</returns> public bool equalTo(UFileInfo ufi) { if (this.fileSize == ufi.fileSize && this.hashMD5 == ufi.hashMD5) { return(true); } return(false); }
/// <summary> /// 指定ディレクトリ以下のファイルをファイルのハッシュ(MD5)をキーにした辞書データを作成する。 /// </summary> /// <param name="rootDir">ルートディレクトリパス</param> /// <param name="log">ログ出力先</param> /// <returns>ファイル辞書データ(ファイルのハッシュがキー)</returns> public Dictionary <string, UFileInfo> GetFilesInfo2(string rootDir, StringBuilder log, IProgress <MyProgress> p) { //"C:\test"以下の".txt"ファイルをすべて取得する DirectoryInfo di = new DirectoryInfo(rootDir); FileInfo[] files = di.GetFiles("*.*", System.IO.SearchOption.AllDirectories); var myProgress = new MyProgress("GetFilesInfo2", 0); int processCnt = 0; var dic = new Dictionary <string, UFileInfo>(); p.Report(myProgress); foreach (FileInfo f in files) { if (cancelFlag) { throw new Exception("キャンセルされました"); } string key = getFileMD5(f.FullName); string fileName = Path.GetFileName(f.FullName); string filePath = Path.GetDirectoryName(f.FullName).Replace(rootDir, ""); if (dic.ContainsKey(key) == false) { UFileInfo ufi = new UFileInfo(fileName, filePath, f.Length, f.LastWriteTime, key); dic[key] = ufi; } else { log.AppendLine(Path.Combine(filePath, fileName) + "は既に存在します。(" + Path.Combine(dic[key].filePath, dic[key].fileName) + "と同じファイル)"); } processCnt++; myProgress.Progress = (int)((float)processCnt / (float)files.Length * 100.0f); p.Report(myProgress); } return(dic); }
/// <summary> /// ファイル移動実行メイン /// </summary> /// <param name="srcRoot"></param> /// <param name="destRoot"></param> /// <param name="mode">1:移動 / 2:移動なし</param> /// <returns></returns> public string Main(string srcRoot, string destRoot, int mode, IProgress <MyProgress> p) { var log = new StringBuilder(); int moveFileCnt = 0; int fileCnt = 0; var myProgress = new MyProgress("Main", 0); srcRootPath = srcRoot; destRootPath = destRoot; try { log.AppendLine("*** new リストを作成する ***"); srcFiles = GetFilesInfo2(srcRoot, log, p); log.AppendLine("*** old リストを作成する ***"); destFiles = GetFilesInfo(destRoot, p); renameCopyList = new List <string>(); p.Report(myProgress); // destFilesのファイルをsrcFilesから探す // 見つかったらsrcFilesのルートと同じ場所に移動する foreach (UFileInfo ufi in destFiles) { if (cancelFlag) { throw new Exception("Canceled"); } if (srcFiles.ContainsKey(ufi.hashMD5)) { UFileInfo ufi2 = srcFiles[ufi.hashMD5]; if (ufi.equalTo(ufi2)) { // 移動 if (ufi.filePath != ufi2.filePath || ufi.fileName != ufi2.fileName) { string path1 = destRootPath + ufi.filePath + @"\" + ufi.fileName; string path2 = destRootPath + ufi2.filePath + @"\" + ufi2.fileName; // 移動先のフォルダが存在しないなら作成する if (Directory.Exists(destRootPath + ufi2.filePath) == false) { string dirPath = destRootPath + ufi2.filePath; if (mode == 1) { Directory.CreateDirectory(dirPath); } log.AppendLine("Create Folder: " + dirPath); } if (mode == 1) { // 移動先に同名のファイルが存在していたらリネームしてコピー if (File.Exists(path2) == true) { // 後で .tmpを除去するためにリストに追加 renameCopyList.Add(path2); path2 += ".tmp"; } File.Move(path1, path2); } log.AppendLine("Move File: From " + ufi.filePath + @"\" + ufi.fileName + " To " + ufi2.filePath + @"\" + ufi2.fileName); moveFileCnt++; } } } fileCnt++; myProgress.Progress = (int)((float)fileCnt / (float)destFiles.Count * 100.0f); p.Report(myProgress); } // .tmpをつけてコピーしたファイルを元の名前に戻す foreach (string fileName in renameCopyList) { File.Move(fileName + ".tmp", fileName); } myProgress.Progress = 100; p.Report(myProgress); log.AppendLine(moveFileCnt + "個のファイルを移動しました。"); } catch (Exception e) { log.AppendLine("Error: " + e.Message); } return(log.ToString()); }