Newer
Older
wbackup / wbackup / wBackupEngine.cs
@Kunihiro Narita Kunihiro Narita on 18 Sep 2020 4 KB Stream処理するように再設計
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<string> sourceFolder = new List<string>();
        protected List<string> ignoreFolder = new List<string>();
        protected ConcurrentBag<string> abortedFile = new ConcurrentBag<string>();
        protected ConcurrentBag<string> completeFile = new ConcurrentBag<string>();
        protected ConcurrentBag<HardLinkFile> hardLinkList = new ConcurrentBag<HardLinkFile>();
        protected List<ConcurrentQueue<string>> compressQueue = new List<ConcurrentQueue<string>>();

        public wBackupEngine()
        {

        }

        /// <summary>
        /// バックアップ対象フォルダを追加する
        /// </summary>
        /// <param name="newFolder"></param>
        public void AddSourceFolder(string newFolder)
        {
            sourceFolder.Add(newFolder);
        }

        /// <summary>
        /// バックアップ除外フォルダを追加する
        /// </summary>
        /// <param name="newFolder"></param>
        public void AddIgnoreFolder(string newFolder)
        {
            ignoreFolder.Add(newFolder);
        }

        public void Do()
        {

        }

        /// <summary>
        /// バックアップ対象ファイルを列挙する
        /// </summary>
        protected async Task ListingSourceFiles()
        {
            await Task.Run(() =>
            {
                foreach (string rootFolder in sourceFolder)
                {
                    ListingSourceFiles(rootFolder);
                }
            });
        }

        /// <summary>
        /// ソースファイルのリストを作成する
        /// </summary>
        /// <param name="rootFolder"></param>
        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);
                }
            }
        }

        /// <summary>
        /// ファイル先頭4KBからハッシュ値を算出する
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        protected uint CalclateHash(string fileName)
        {
            byte[] readbuff = new byte[1024 * 4];
            Array.Clear(readbuff, 0, readbuff.Length);
            Vector<uint> hashTemp1 = Vector<uint>.Zero;
            Vector<uint> hashTemp2 = Vector<uint>.Zero;
            using (var fs = File.OpenRead(fileName))
            {
                int readLen = fs.Read(readbuff, 0, readbuff.Length);
                fs.Close();
                ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(readbuff);
                for (int i = 0; i < readbuff.Length; i += Vector<int>.Count * sizeof(int))
                {
                    hashTemp2 = new Vector<uint>(span.Slice(i, Vector<uint>.Count * sizeof(uint)));
                    hashTemp1 ^= hashTemp2;
                }
            }

            uint hashValue = 0;
            for (int i = 0; i < Vector<int>.Count; i++)
            {
                hashValue ^= hashTemp1[i];
            }

            return hashValue;
        }

    }
}