怎样用 C# 快速比较 2 个文件是否是相同的文件?
2019-03-22 23:31 音乐让我说 阅读(893) 评论(0) 编辑 收藏 举报方案1:
直接贴代码了:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; namespace FileCompareDemo { public class FileHelper { const int BYTES_TO_READ = sizeof(Int64); public static bool FilesAreEqual(FileInfo first, FileInfo second) { if (first.Length != second.Length) return false; if (string.Equals(first.FullName, second.FullName, StringComparison.OrdinalIgnoreCase)) return true; int iterations = (int)Math.Ceiling((double)first.Length / BYTES_TO_READ); using (FileStream fs1 = first.OpenRead()) using (FileStream fs2 = second.OpenRead()) { byte[] one = new byte[BYTES_TO_READ]; byte[] two = new byte[BYTES_TO_READ]; for (int i = 0; i < iterations; i++) { fs1.Read(one, 0, BYTES_TO_READ); fs2.Read(two, 0, BYTES_TO_READ); if (BitConverter.ToInt64(one, 0) != BitConverter.ToInt64(two, 0)) return false; } } return true; } public static bool FilesAreEqual_OneByte(FileInfo first, FileInfo second) { if (first.Length != second.Length) return false; if (string.Equals(first.FullName, second.FullName, StringComparison.OrdinalIgnoreCase)) return true; using (FileStream fs1 = first.OpenRead()) using (FileStream fs2 = second.OpenRead()) { for (int i = 0; i < first.Length; i++) { if (fs1.ReadByte() != fs2.ReadByte()) return false; } } return true; } public static bool FilesAreEqual_Hash(FileInfo first, FileInfo second) { byte[] firstHash = MD5.Create().ComputeHash(first.OpenRead()); byte[] secondHash = MD5.Create().ComputeHash(second.OpenRead()); for (int i = 0; i < firstHash.Length; i++) { if (firstHash[i] != secondHash[i]) return false; } return true; } } }
方案2:
直接贴代码了:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FileCompareDemo { public static class FileHelper2 { public static bool FilesContentsAreEqual(FileInfo fileInfo1, FileInfo fileInfo2) { if (fileInfo1 == null) { throw new ArgumentNullException(nameof(fileInfo1)); } if (fileInfo2 == null) { throw new ArgumentNullException(nameof(fileInfo2)); } if (string.Equals(fileInfo1.FullName, fileInfo2.FullName, StringComparison.OrdinalIgnoreCase)) { return true; } if (fileInfo1.Length != fileInfo2.Length) { return false; } else { using (var file1 = fileInfo1.OpenRead()) { using (var file2 = fileInfo2.OpenRead()) { return StreamsContentsAreEqual(file1, file2); } } } } private static int ReadFullBuffer(Stream stream, byte[] buffer) { int bytesRead = 0; while (bytesRead < buffer.Length) { int read = stream.Read(buffer, bytesRead, buffer.Length - bytesRead); if (read == 0) { // Reached end of stream. return bytesRead; } bytesRead += read; } return bytesRead; } private static bool StreamsContentsAreEqual(Stream stream1, Stream stream2) { const int bufferSize = 1024 * sizeof(Int64); var buffer1 = new byte[bufferSize]; var buffer2 = new byte[bufferSize]; while (true) { int count1 = ReadFullBuffer(stream1, buffer1); int count2 = ReadFullBuffer(stream2, buffer2); if (count1 != count2) { return false; } if (count1 == 0) { return true; } int iterations = (int)Math.Ceiling((double)count1 / sizeof(Int64)); for (int i = 0; i < iterations; i++) { if (BitConverter.ToInt64(buffer1, i * sizeof(Int64)) != BitConverter.ToInt64(buffer2, i * sizeof(Int64))) { return false; } } } } } }
方案3(异步版本):
直接贴代码了:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FileCompareDemo { public static class FileCompareAsyncHelper { static void test(string filePath1, string filePath2) { var fi1 = new FileInfo(filePath1); var fi2 = new FileInfo(filePath2); Console.WriteLine(FilesContentsAreEqualAsync(fi1, fi2).GetAwaiter().GetResult()); } public static async Task<bool> FilesContentsAreEqualAsync(FileInfo fileInfo1, FileInfo fileInfo2) { if (fileInfo1 == null) { throw new ArgumentNullException(nameof(fileInfo1)); } if (fileInfo2 == null) { throw new ArgumentNullException(nameof(fileInfo2)); } if (string.Equals(fileInfo1.FullName, fileInfo2.FullName, StringComparison.OrdinalIgnoreCase)) { return true; } if (fileInfo1.Length != fileInfo2.Length) { return false; } else { using (var file1 = fileInfo1.OpenRead()) { using (var file2 = fileInfo2.OpenRead()) { return await StreamsContentsAreEqualAsync(file1, file2).ConfigureAwait(false); } } } } private static async Task<int> ReadFullBufferAsync(Stream stream, byte[] buffer) { int bytesRead = 0; while (bytesRead < buffer.Length) { int read = await stream.ReadAsync(buffer, bytesRead, buffer.Length - bytesRead).ConfigureAwait(false); if (read == 0) { // Reached end of stream. return bytesRead; } bytesRead += read; } return bytesRead; } private static async Task<bool> StreamsContentsAreEqualAsync(Stream stream1, Stream stream2) { const int bufferSize = 1024 * sizeof(Int64); var buffer1 = new byte[bufferSize]; var buffer2 = new byte[bufferSize]; while (true) { int count1 = await ReadFullBufferAsync(stream1, buffer1).ConfigureAwait(false); int count2 = await ReadFullBufferAsync(stream2, buffer2).ConfigureAwait(false); if (count1 != count2) { return false; } if (count1 == 0) { return true; } int iterations = (int)Math.Ceiling((double)count1 / sizeof(Int64)); for (int i = 0; i < iterations; i++) { if (BitConverter.ToInt64(buffer1, i * sizeof(Int64)) != BitConverter.ToInt64(buffer2, i * sizeof(Int64))) { return false; } } } } } }
谢谢浏览!
作者:音乐让我说(音乐让我说 - 博客园)
出处:http://music.cnblogs.com/
文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。