起因
写代码有时,需要对比一下文件是改动了,就写了这工具。其实用SVN 或者GIT比较也很方便。
实现
private void button1_Click(object sender, EventArgs e)
{
var comparer = new DirectoryFileComparer();
// 比较两个目录,将结果保存到指定文件
comparer.CompareCommonFiles(
textBox1.Text.Trim(), // 源目录
textBox2.Text.Trim(), // 目标目录
@"d:\filechanges.txt" // 结果输出文件
);
}
CompareCommonFiles的处理
找出两个目录都存在但内容不同的文件
var differentFiles = FindCommonButDifferentFiles(sourceDir, targetDir, sourceFiles, targetFiles);
需要比较的文件扩展名
private readonly string[] _targetExtensions = { ".cs", ".aspx", ".js" };
比较文件
foreach (var relativePath in commonFiles)
{
var sourceFilePath = sourceDir + "" + relativePath;// Path.Combine(sourceDir, relativePath);
var targetFilePath = targetDir + "" + relativePath; //Path.Combine(targetDir, relativePath);
if (File.Exists(sourceFilePath))
if (File.Exists(targetFilePath))
{
string s1 = System.IO.File.ReadAllText(sourceFilePath);
string s2 = System.IO.File.ReadAllText(targetFilePath);
if (s1!=s2)
differentFiles.Add(relativePath);
// 比较文件内容
//if (!FilesContentsEqual(sourceFilePath, targetFilePath))
//{
// differentFiles.Add(relativePath);
//}
}
}
FilesContentsEqual的处理
可能有人会问为啥不用MD5 进行比较?
在这里用MD5 如果是大文件的话,其实更慢,而且也没有必要。
/// <summary>
/// 比较两个文件的内容是否相同
/// </summary>
private bool FilesContentsEqual(string path1, string path2)
{
// 先比较文件大小,不同则内容肯定不同
var fileInfo1 = new FileInfo(path1);
var fileInfo2 = new FileInfo(path2);
if (fileInfo1.Length != fileInfo2.Length)
return false;
// 对于空文件,直接返回相同
if (fileInfo1.Length == 0)
return true;
// 比较文件内容(使用缓冲流提高效率)
using (var stream1 = fileInfo1.OpenRead())
using (var stream2 = fileInfo2.OpenRead())
{
const int bufferSize = 8192;
byte[] buffer1 = new byte[bufferSize];
byte[] buffer2 = new byte[bufferSize];
int bytesRead;
while ((bytesRead = stream1.Read(buffer1, 0, bufferSize)) > 0)
{
// 读取第二个文件的相同字节数
int bytesRead2 = stream2.Read(buffer2, 0, bufferSize);
// 如果读取的字节数不同,文件内容不同
if (bytesRead != bytesRead2)
return false;
// 比较缓冲区内容
for (int i = 0; i < bytesRead; i++)
{
if (buffer1[i] != buffer2[i])
return false;
}
}
}
return true;
}
代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DirComparer
{
public class DirectoryFileComparer
{
// 需要比较的文件扩展名
private readonly string[] _targetExtensions = { ".cs", ".aspx", ".js" };
/// <summary>
/// 比较两个目录,找出共同存在但内容不同的文件
/// </summary>
/// <param name="sourceDir">源目录路径</param>
/// <param name="targetDir">目标目录路径</param>
/// <param name="outputFile">结果输出文件路径</param>
/// <returns>是否成功完成比较</returns>
public bool CompareCommonFiles(string sourceDir, string targetDir, string outputFile)
{
try
{
// 验证目录是否存在
if (!Directory.Exists(sourceDir))
{
Console.WriteLine($"源目录不存在: {sourceDir}");
return false;
}
if (!Directory.Exists(targetDir))
{
Console.WriteLine($"目标目录不存在: {targetDir}");
return false;
}
// 获取两个目录中符合条件的所有文件
var sourceFiles = GetFilesWithExtensions(sourceDir);
var targetFiles = GetFilesWithExtensions(targetDir);
// 找出两个目录都存在但内容不同的文件
var differentFiles = FindCommonButDifferentFiles(sourceDir, targetDir, sourceFiles, targetFiles);
// 保存结果到文件
SaveResults(differentFiles, outputFile);
Console.WriteLine($"比较完成,共发现 {differentFiles.Count} 个共同存在但内容不同的文件,结果已保存到 {outputFile}");
return true;
}
catch (Exception ex)
{
Console.WriteLine($"比较过程中发生错误: {ex.Message}");
return false;
}
}
/// <summary>
/// 获取目录中指定扩展名的所有文件(相对路径)
/// </summary>
private List<string> GetFilesWithExtensions(string directory)
{
var files = new List<string>();
foreach (var ext in _targetExtensions)
{
// 获取所有符合扩展名的文件,包括子目录
files.AddRange(Directory.GetFiles(directory, $"*{ext}", SearchOption.AllDirectories));
}
// 转换为相对于根目录的路径,便于比较
return files.Select(file => file.Substring(directory.Length)).ToList();
}
/// <summary>
/// 找出两个目录都存在但内容不同的文件
/// </summary>
private List<string> FindCommonButDifferentFiles(string sourceDir, string targetDir,
List<string> sourceFiles, List<string> targetFiles)
{
var differentFiles = new List<string>();
// 找出两个目录都存在的文件
var commonFiles = sourceFiles.Intersect(targetFiles);
foreach (var relativePath in commonFiles)
{
var sourceFilePath = sourceDir + "" + relativePath;// Path.Combine(sourceDir, relativePath);
var targetFilePath = targetDir + "" + relativePath; //Path.Combine(targetDir, relativePath);
if (File.Exists(sourceFilePath))
if (File.Exists(targetFilePath))
{
string s1 = System.IO.File.ReadAllText(sourceFilePath);
string s2 = System.IO.File.ReadAllText(targetFilePath);
if (s1!=s2)
differentFiles.Add(relativePath);
// 比较文件内容
//if (!FilesContentsEqual(sourceFilePath, targetFilePath))
//{
// differentFiles.Add(relativePath);
//}
}
}
return differentFiles;
}
/// <summary>
/// 比较两个文件的内容是否相同
/// </summary>
private bool FilesContentsEqual(string path1, string path2)
{
// 先比较文件大小,不同则内容肯定不同
var fileInfo1 = new FileInfo(path1);
var fileInfo2 = new FileInfo(path2);
if (fileInfo1.Length != fileInfo2.Length)
return false;
// 对于空文件,直接返回相同
if (fileInfo1.Length == 0)
return true;
// 比较文件内容(使用缓冲流提高效率)
using (var stream1 = fileInfo1.OpenRead())
using (var stream2 = fileInfo2.OpenRead())
{
const int bufferSize = 8192;
byte[] buffer1 = new byte[bufferSize];
byte[] buffer2 = new byte[bufferSize];
int bytesRead;
while ((bytesRead = stream1.Read(buffer1, 0, bufferSize)) > 0)
{
// 读取第二个文件的相同字节数
int bytesRead2 = stream2.Read(buffer2, 0, bufferSize);
// 如果读取的字节数不同,文件内容不同
if (bytesRead != bytesRead2)
return false;
// 比较缓冲区内容
for (int i = 0; i < bytesRead; i++)
{
if (buffer1[i] != buffer2[i])
return false;
}
}
}
return true;
}
/// <summary>
/// 将比较结果保存到文件
/// </summary>
private void SaveResults(List<string> differentFiles, string outputFile)
{
// 确保输出目录存在
var outputDir = Path.GetDirectoryName(outputFile);
if (!string.IsNullOrEmpty(outputDir) && !Directory.Exists(outputDir))
{
Directory.CreateDirectory(outputDir);
}
// 写入结果,包含时间戳
using (var writer = new StreamWriter(outputFile))
{
writer.WriteLine($"两个目录中共同存在但内容不同的文件 - {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
writer.WriteLine("==========================================");
writer.WriteLine();
if (differentFiles.Count == 0)
{
writer.WriteLine("未发现共同存在但内容不同的文件");
}
else
{
foreach (var file in differentFiles)
{
writer.WriteLine(file);
}
}
}
}
}
}
7462

被折叠的 条评论
为什么被折叠?



