一种直观的方法是,直接用一个文件存储该文件夹的创建时间,之后看创建时间是否发生改变,能够判断文件夹内容是否被更改。但是如果文件夹创建时间更改了,文件内容可以先改了再改回来,这时候有什么性能比较好的办法可以检查文件夹的完整性呢?对文件夹所有文件内容作md5计算消耗的性能太大。
可以使用文件夹的文件名称的排列顺序与文件内容大小的对应关系,建立一个有序的字符串,最后将文件夹的文件总数目+遍历的文件夹大小序列+文件夹的总大小作md5的计算。
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
string dir = @"C:\Users\Administrator\AppData\Roaming\huyapclive\Packages\CefSharp\96.0.18.1";
int dirFileCount = 0;
long dirSize = 0;
string content = "";
long timespan2 = DateTime.Now.Ticks;
GetFileSizeAndCount(dir, ref dirFileCount, ref dirSize, ref content);
timespan2 = DateTime.Now.Ticks - timespan2;
Console.WriteLine($"花费时间:{timespan2 / 10000} ms 文件数目为:{dirFileCount} 文件大小为:{dirSize}");
content = dirFileCount.ToString() + content + dirSize.ToString();
Console.WriteLine($"拼接得到的字符串为:{content}");
string smd5= ConvertStringToMd5(content);
Console.WriteLine($"计算得到字符串对应的md5为:{smd5}");
}
//获取文件夹文件个数
public static void GetFileSizeAndCount(string dir, ref int dirFileCount, ref long dirSize, ref string content)
{
try
{
DirectoryInfo dirInfo = new DirectoryInfo(dir);
DirectoryInfo[] dirs = dirInfo.GetDirectories();
FileInfo[] files = dirInfo.GetFiles();
foreach (var item in dirs)
{
GetFileSizeAndCount(item.FullName, ref dirFileCount, ref dirSize, ref content);
}
dirFileCount += files.Length;
foreach (var item in files)
{
dirSize += item.Length;
content += item.Length.ToString();
}
}
catch (Exception ex)
{
Console.WriteLine("获取文件夹文件个数失败" + ex.Message);
}
}
// 根据内容计算md5
private static string ConvertStringToMd5(string content)
{
try
{
byte[] btcontent = Encoding.ASCII.GetBytes(content);
System.Security.Cryptography.MD5 file_md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] ret = file_md5.ComputeHash(btcontent);
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < ret.Length; ++i)
{
sBuilder.Append(ret[i].ToString("x2"));
}
return sBuilder.ToString();
}
catch { }
return "";
}
}
}