diff --git a/DuplicateCheck/DuplicateCheck.csproj b/DuplicateCheck/DuplicateCheck.csproj
new file mode 100644
index 0000000..c73e0d1
--- /dev/null
+++ b/DuplicateCheck/DuplicateCheck.csproj
@@ -0,0 +1,8 @@
+
+
+
+ Exe
+ netcoreapp3.1
+
+
+
diff --git a/DuplicateCheck/Program.cs b/DuplicateCheck/Program.cs
new file mode 100644
index 0000000..737e126
--- /dev/null
+++ b/DuplicateCheck/Program.cs
@@ -0,0 +1,87 @@
+using System;
+using System.IO;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+
+namespace DuplicateCheck
+{
+ class DuplicateCheckInfo
+ {
+ public string fileName;
+ public byte[] hashValue;
+ public long fileSize;
+
+ public ulong HashKey
+ {
+ get
+ {
+ ulong hashKey = 0;
+ for (int i = 0; i < sizeof(ulong); i++)
+ {
+ hashKey = (hashKey << 8) ^ hashValue[i];
+ }
+ return hashKey;
+ }
+ }
+
+ public DuplicateCheckInfo(string fileName)
+ {
+ this.fileName = fileName;
+ var hash = SHA256.Create();
+ using (FileStream fs = File.OpenRead(fileName))
+ {
+ fileSize = fs.Length;
+ if (fileSize > 4096)
+ {
+ hash.ComputeHash(fs);
+ hashValue = hash.Hash;
+ }
+ }
+ }
+
+ public bool IsMatch(DuplicateCheckInfo srce)
+ {
+ if (this.fileSize != srce.fileSize)
+ return false;
+
+ for (int i = 0;i < hashValue.Length;i ++)
+ {
+ if (hashValue[i] != srce.hashValue[i])
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Console.WriteLine("Duplicate Check Test Logic.");
+ Dictionary hashData = new Dictionary();
+ foreach (var item in Directory.GetFiles(@"D:\Projects\", "*", SearchOption.AllDirectories))
+ {
+ DuplicateCheckInfo info = new DuplicateCheckInfo(item);
+ if (info.fileSize > 4096)
+ {
+ ulong hashValue = info.HashKey;
+ if (hashData.TryGetValue(hashValue, out DuplicateCheckInfo srceInfo))
+ {
+ if (srceInfo.IsMatch(info))
+ {
+ Console.WriteLine("Duplicate {0}, {1}", item, srceInfo.fileName);
+ Console.WriteLine("Copy-Item -Path \"{0}\" -Destination \"{1}\"", srceInfo.fileName, item);
+ Console.WriteLine("Set-ItemProperty -Path \"{0}\" -Name LastWriteTime -Value \"{1}\"", item, File.GetLastWriteTime(item).ToString("yyyy-MM-dd HH:mm:ss"));
+ }
+ }
+ else
+ {
+ hashData.Add(hashValue, info);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/wbackup/ArchiveTarFile.cs b/wbackup/ArchiveTarFile.cs
index 1492b38..c339e61 100644
--- a/wbackup/ArchiveTarFile.cs
+++ b/wbackup/ArchiveTarFile.cs
@@ -26,8 +26,7 @@
public ArchiveTarFile(string exportPath, BackupStreamBase stream = null):base(stream)
{
- string postFixString = DateTime.Now.ToString("yyyyMMddHHmmss");
- string zipFileName = exportPath + postFixString + ".tar.gz";
+ string zipFileName = exportPath + ".tar.gz";
// 出力先ストリームのインスタンス生成
fileOutputStream = new FileStream(zipFileName, FileMode.Create, FileAccess.Write);
diff --git a/wbackup/Program.cs b/wbackup/Program.cs
index 598dc45..37bb285 100644
--- a/wbackup/Program.cs
+++ b/wbackup/Program.cs
@@ -33,24 +33,26 @@
// 出力先インスタンスを生成する
ParallelBackup parallel = new ParallelBackup();
+ string postFixString = DateTime.Now.ToString("yyyyMMddHHmmss");
for (int i = 0; i < param.maxThreadCount; i++)
{
- string exportFileName = param.destinationDir + "-" + i.ToString("00") + "-";
+ string exportFileName = param.destinationDir + "-" + postFixString + "-" + i.ToString("00");
parallel.AddNextStream(new ArchiveTarFile(exportFileName, new ClearArchiveFlag()));
}
// バックアップエンジンのインスタンスを生成する
if (param.backupMode == BackupMopde.Full)
{
- backupEngine = new ListingAllSourceFile(parallel);
+ //backupEngine = new ListingAllSourceFile(parallel);
+ backupEngine = new ListingAllSourceFile(new RejectDuplicateFile(param.destinationDir + "-" + postFixString + ".ps1", parallel));
}
if (param.backupMode == BackupMopde.Incremental)
{
- backupEngine = new ListingArchiveSourceFile(parallel);
+ backupEngine = new ListingArchiveSourceFile(new RejectDuplicateFile(param.destinationDir + "-" + postFixString + ".ps1", parallel));
}
if (param.backupMode == BackupMopde.Differencial)
{
- backupEngine = new ListingArchiveSourceFile(parallel);
+ backupEngine = new ListingArchiveSourceFile(new RejectDuplicateFile(param.destinationDir + "-" + postFixString + ".ps1", parallel));
}
foreach (var ignoreFile in param.ignoreFile)
diff --git a/wbackup/Properties/launchSettings.json b/wbackup/Properties/launchSettings.json
index a5ae103..496cd2d 100644
--- a/wbackup/Properties/launchSettings.json
+++ b/wbackup/Properties/launchSettings.json
@@ -2,7 +2,7 @@
"profiles": {
"wbackup": {
"commandName": "Project",
- "commandLineArgs": "-srce \"D:\\Projects\\atozip\" -dest \"D:\\backup\\archive\" -log \"D:\\backup\\archive\" -incremental -ignore D:\\Projects\\atozip\\.git\\ -ignore D:\\Projects\\atozip\\.vs\\"
+ "commandLineArgs": "-srce \"D:\\Projects\\atozip\" -dest \"D:\\backup\\archive\" -log \"D:\\backup\\archive\" -full"
}
}
}
\ No newline at end of file
diff --git a/wbackup/RejectDuplicateFile.cs b/wbackup/RejectDuplicateFile.cs
new file mode 100644
index 0000000..f5fa511
--- /dev/null
+++ b/wbackup/RejectDuplicateFile.cs
@@ -0,0 +1,113 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Security.Cryptography;
+
+namespace wbackup
+{
+ class DuplicateCheckInfo
+ {
+ public string fileName;
+ public byte[] hashValue;
+ public long fileSize;
+
+ public ulong HashKey
+ {
+ get
+ {
+ ulong hashKey = 0;
+ for (int i = 0; i < sizeof(ulong); i++)
+ {
+ hashKey = (hashKey << 8) ^ hashValue[i];
+ }
+ return hashKey;
+ }
+ }
+
+ public DuplicateCheckInfo(string fileName)
+ {
+ this.fileName = fileName;
+ var hash = SHA256.Create();
+ using (FileStream fs = File.OpenRead(fileName))
+ {
+ fileSize = fs.Length;
+ if (fileSize > 4096)
+ {
+ hash.ComputeHash(fs);
+ hashValue = hash.Hash;
+ }
+ }
+ }
+
+ public bool IsMatch(DuplicateCheckInfo srce)
+ {
+ if (this.fileSize != srce.fileSize)
+ return false;
+
+ for (int i = 0; i < hashValue.Length; i++)
+ {
+ if (hashValue[i] != srce.hashValue[i])
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ class RejectDuplicateFile : BackupStreamBase
+ {
+ protected string recoveryScriptName;
+ protected Dictionary hashData;
+
+ public RejectDuplicateFile(string scriptName, BackupStreamBase stream = null) : base(stream)
+ {
+ recoveryScriptName = scriptName;
+ hashData = new Dictionary();
+ }
+
+ protected override void DoWork(string sourceFileName)
+ {
+ if (sourceFileName == "")
+ AddNextSource(sourceFileName);
+
+ DuplicateCheckInfo info = new DuplicateCheckInfo(sourceFileName);
+ if (info.fileSize > 4096)
+ {
+ ulong hashValue = info.HashKey;
+ if (hashData.TryGetValue(hashValue, out DuplicateCheckInfo srceInfo))
+ {
+ if (srceInfo.IsMatch(info))
+ {
+ Console.WriteLine("Duplicate {0}, {1}", sourceFileName, srceInfo.fileName);
+
+ StringBuilder script = new StringBuilder();
+ string destDir = sourceFileName.Substring(0, sourceFileName.LastIndexOf("\\") + 1);
+ script.AppendFormat("New-Item -Path \"{0}\" -ItemType Directory", destDir);
+ script.AppendLine();
+ script.AppendFormat("Copy-Item -Path \"{0}\" -Destination \"{1}\"", srceInfo.fileName, sourceFileName);
+ script.AppendLine();
+ script.AppendFormat("Set-ItemProperty -Path \"{0}\" -Name LastWriteTime -Value \"{1}\"", sourceFileName, File.GetLastWriteTime(sourceFileName).ToString("yyyy-MM-dd HH:mm:ss"));
+ script.AppendLine();
+ File.AppendAllText(recoveryScriptName, script.ToString());
+ }
+ else
+ {
+ AddNextSource(sourceFileName);
+ }
+ }
+ else
+ {
+ hashData.Add(hashValue, info);
+ AddNextSource(sourceFileName);
+ }
+ }
+ else
+ {
+ AddNextSource(sourceFileName);
+ }
+ }
+ }
+}
diff --git a/wbackup/wbackup.csproj b/wbackup/wbackup.csproj
index 29d6f97..9090ef9 100644
--- a/wbackup/wbackup.csproj
+++ b/wbackup/wbackup.csproj
@@ -16,7 +16,7 @@
-
+