diff --git a/ClearArchiveFlag.,cs b/ClearArchiveFlag.,cs new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/ClearArchiveFlag.,cs diff --git a/wbackup.sln b/wbackup.sln index feda39d..6b7554f 100644 --- a/wbackup.sln +++ b/wbackup.sln @@ -3,7 +3,7 @@ # Visual Studio Version 16 VisualStudioVersion = 16.0.30413.136 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wbackup", "wbackup\wbackup.csproj", "{1EA6ED4D-C97F-4CBA-B30D-786647B21198}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "wbackup", "wbackup\wbackup.csproj", "{1EA6ED4D-C97F-4CBA-B30D-786647B21198}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/wbackup/ArchiveTarFile.cs b/wbackup/ArchiveTarFile.cs index b58c566..51bbdc1 100644 --- a/wbackup/ArchiveTarFile.cs +++ b/wbackup/ArchiveTarFile.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Text; using System.IO; +using System.Threading; using System.Threading.Tasks; using ICSharpCode.SharpZipLib.GZip; using ICSharpCode.SharpZipLib.Tar; @@ -15,9 +16,11 @@ protected GZipOutputStream gzipOutputStream; protected TarOutputStream tarOutputStream; + protected int archiveCount; protected int buffSelect; protected int buffSize; protected byte[][] readBuffer; + protected DateTime minLastWriteDate; public ArchiveTarFile(string exportPath, BackupStreamBase stream = null):base(stream) { @@ -36,6 +39,9 @@ readBuffer = new byte[2][]; readBuffer[0] = new byte[buffSize]; readBuffer[1] = new byte[buffSize]; + + archiveCount = 0; + minLastWriteDate = DateTime.Parse("1970-12-01"); } protected override void DisposeManagedResource() @@ -46,8 +52,17 @@ protected override void DoWork(string sourceFileName) { + Console.WriteLine("Archive {0}, {1}", Interlocked.Increment(ref archiveCount), sourceFileName); + using (var fis = new FileStream(sourceFileName, FileMode.Open, FileAccess.Read)) { + // 最終書込日時が小さい場合には書き換えておく + var lastWriteTime = File.GetLastWriteTime(sourceFileName); + if (lastWriteTime < minLastWriteDate) + { + File.SetLastWriteTime(sourceFileName, minLastWriteDate); + } + // ZIPファイルヘッダ作成 TarEntry tarEntry = TarEntry.CreateEntryFromFile(sourceFileName); tarOutputStream.PutNextEntry(tarEntry); @@ -71,6 +86,8 @@ } tarOutputStream.CloseEntry(); + + AddNextSource(sourceFileName); } } } diff --git a/wbackup/ClearArchiveFlag.cs b/wbackup/ClearArchiveFlag.cs new file mode 100644 index 0000000..6575a67 --- /dev/null +++ b/wbackup/ClearArchiveFlag.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace wbackup +{ + class ClearArchiveFlag : BackupStreamBase + { + protected int archiveCount; + + public ClearArchiveFlag(BackupStreamBase stream = null) : base(stream) + { + archiveCount = 0; + } + + protected override void DoWork(string sourceFileName) + { + Console.WriteLine("Clear {0}, {1}", Interlocked.Increment(ref archiveCount), sourceFileName); + + var attributes = File.GetAttributes(sourceFileName); + if (attributes.HasFlag(FileAttributes.Archive)) + { + attributes = attributes & ~FileAttributes.Archive; + File.SetAttributes(sourceFileName, attributes); + } + } + } +} diff --git a/wbackup/ListingAllSourceFile.cs b/wbackup/ListingAllSourceFile.cs index 2c2beb2..16cacb2 100644 --- a/wbackup/ListingAllSourceFile.cs +++ b/wbackup/ListingAllSourceFile.cs @@ -18,7 +18,6 @@ } - /// /// バックアップ除外フォルダを追加する /// diff --git a/wbackup/ListingArchiveSourceFile.cs b/wbackup/ListingArchiveSourceFile.cs new file mode 100644 index 0000000..6eb0775 --- /dev/null +++ b/wbackup/ListingArchiveSourceFile.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections.Concurrent; +using System.Numerics; +using System.IO; +using System.Threading.Tasks; +using System.Text.RegularExpressions; + +namespace wbackup +{ + class ListingArchiveSourceFile : BackupStreamBase + { + protected List ignoreFolder = new List(); + + public ListingArchiveSourceFile(BackupStreamBase stream = null) : base(stream) + { + + } + + /// + /// バックアップ除外フォルダを追加する + /// + /// + public void AddIgnoreFolder(string newFolder) + { + ignoreFolder.Add(newFolder); + } + + protected override void DoWork(string sourceFileName) + { + ListingSourceFiles(sourceFileName); + } + + /// + /// ソースファイルのリストを作成する + /// + /// + protected void ListingSourceFiles(string rootFolder) + { + foreach (string fileName in Directory.GetFiles(rootFolder)) + { + if (false == isIgnoreFile(fileName)) + { + var fileAttrib = File.GetAttributes(fileName); + if (false == fileAttrib.HasFlag(FileAttributes.Hidden) && true == fileAttrib.HasFlag(FileAttributes.Archive)) + { + File.SetAttributes(fileName, fileAttrib | FileAttributes.Archive); + AddNextSource(fileName); + } + } + } + + foreach (string directory in Directory.GetDirectories(rootFolder)) + { + var dirAttrib = File.GetAttributes(directory); + if (false == dirAttrib.HasFlag(FileAttributes.Hidden)) + { + ListingSourceFiles(directory); + } + } + } + + /// + /// バックアップ対象外ファイルか判定する + /// + /// + /// + protected bool isIgnoreFile(string sourceFileName) + { + foreach (var ignoreInfo in ignoreFolder) + { + if (Regex.IsMatch(sourceFileName, ignoreInfo)) + { + return true; + } + } + + return false; + } + } +} diff --git a/wbackup/Program.cs b/wbackup/Program.cs index 4db4e9e..e44832a 100644 --- a/wbackup/Program.cs +++ b/wbackup/Program.cs @@ -20,14 +20,29 @@ { static void Main(string[] args) { - Console.WriteLine("IsHardwareAccelerated = {0}.", Vector.IsHardwareAccelerated); - CommandParser param = new CommandParser(args); - ListingAllSourceFile backupEngine = new ListingAllSourceFile(new ArchiveTarFile(param.destinationDir)); - backupEngine.AddSource(param.sourceDir); - backupEngine.AddSource(""); - backupEngine.Start();  + if (param.backupMode == BackupMopde.Full) + { + ListingAllSourceFile backupEngine = new ListingAllSourceFile(new ArchiveTarFile(param.destinationDir, new ClearArchiveFlag())); + backupEngine.AddSource(param.sourceDir); + backupEngine.AddSource(""); + backupEngine.Start(); + } + if (param.backupMode == BackupMopde.Incremental) + { + ListingArchiveSourceFile backupEngine = new ListingArchiveSourceFile(new ArchiveTarFile(param.destinationDir)); + backupEngine.AddSource(param.sourceDir); + backupEngine.AddSource(""); + backupEngine.Start(); + } + if (param.backupMode == BackupMopde.Differencial) + { + ListingArchiveSourceFile backupEngine = new ListingArchiveSourceFile(new ArchiveTarFile(param.destinationDir, new ClearArchiveFlag())); + backupEngine.AddSource(param.sourceDir); + backupEngine.AddSource(""); + backupEngine.Start(); + } } } } diff --git a/wbackup/wBackupEngine.cs b/wbackup/wBackupEngine.cs deleted file mode 100644 index b8c82f6..0000000 --- a/wbackup/wBackupEngine.cs +++ /dev/null @@ -1,148 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Concurrent; -using System.Numerics; -using System.Text; -using System.IO; -using ICSharpCode.SharpZipLib.GZip; -using ICSharpCode.SharpZipLib.Tar; -using System.Threading.Tasks; -using System.Linq; - -namespace wbackup -{ - class HardLinkFile - { - string sourceFileName; - string distanceFileName; - }; - - class DulplicateCheckDatabase - { - string directory; - string fileName; - uint hashValue; - uint fileSize; - } - - class wBackupEngine - { - protected int maxThread = 4; - protected BackupMopde backupMode = BackupMopde.Full; - protected List sourceFolder = new List(); - protected List ignoreFolder = new List(); - protected ConcurrentBag abortedFile = new ConcurrentBag(); - protected ConcurrentBag completeFile = new ConcurrentBag(); - protected ConcurrentBag hardLinkList = new ConcurrentBag(); - protected List> compressQueue = new List>(); - - public wBackupEngine() - { - - } - - /// - /// バックアップ対象フォルダを追加する - /// - /// - public void AddSourceFolder(string newFolder) - { - sourceFolder.Add(newFolder); - } - - /// - /// バックアップ除外フォルダを追加する - /// - /// - public void AddIgnoreFolder(string newFolder) - { - ignoreFolder.Add(newFolder); - } - - public void Do() - { - - } - - /// - /// バックアップ対象ファイルを列挙する - /// - protected async Task ListingSourceFiles() - { - await Task.Run(() => - { - foreach (string rootFolder in sourceFolder) - { - ListingSourceFiles(rootFolder); - } - }); - } - - /// - /// ソースファイルのリストを作成する - /// - /// - protected void ListingSourceFiles(string rootFolder) - { - foreach (string fileName in Directory.GetFiles(rootFolder)) - { - if (backupMode == BackupMopde.Full) - { - var fileAttrib = File.GetAttributes(fileName); - File.SetAttributes(fileName, fileAttrib | FileAttributes.Archive); - uint hashValue = CalclateHash(fileName); - } - if (backupMode == BackupMopde.Incremental) - { - var fileAttrib = File.GetAttributes(fileName); - if (fileAttrib.HasFlag(FileAttributes.Archive)) - { - uint hashValue = CalclateHash(fileName); - } - } - } - - foreach (string directory in Directory.GetDirectories(rootFolder)) - { - var dirAttrib = File.GetAttributes(directory); - if (false == dirAttrib.HasFlag(FileAttributes.Hidden)) - { - ListingSourceFiles(directory); - } - } - } - - /// - /// ファイル先頭4KBからハッシュ値を算出する - /// - /// - /// - protected uint CalclateHash(string fileName) - { - byte[] readbuff = new byte[1024 * 4]; - Array.Clear(readbuff, 0, readbuff.Length); - Vector hashTemp1 = Vector.Zero; - Vector hashTemp2 = Vector.Zero; - using (var fs = File.OpenRead(fileName)) - { - int readLen = fs.Read(readbuff, 0, readbuff.Length); - fs.Close(); - ReadOnlySpan span = new ReadOnlySpan(readbuff); - for (int i = 0; i < readbuff.Length; i += Vector.Count * sizeof(int)) - { - hashTemp2 = new Vector(span.Slice(i, Vector.Count * sizeof(uint))); - hashTemp1 ^= hashTemp2; - } - } - - uint hashValue = 0; - for (int i = 0; i < Vector.Count; i++) - { - hashValue ^= hashTemp1[i]; - } - - return hashValue; - } - - } -}