怎样用 C# 快速比较 2 个文件是否是相同的文件?
方案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 = ; i < iterations; i++)
{
fs1.Read(one, , BYTES_TO_READ);
fs2.Read(two, , BYTES_TO_READ); if (BitConverter.ToInt64(one, ) != BitConverter.ToInt64(two, ))
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 = ; 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 = ; 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 = ;
while (bytesRead < buffer.Length)
{
int read = stream.Read(buffer, bytesRead, buffer.Length - bytesRead);
if (read == )
{
// Reached end of stream.
return bytesRead;
} bytesRead += read;
} return bytesRead;
} private static bool StreamsContentsAreEqual(Stream stream1, Stream stream2)
{
const int bufferSize = * 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 == )
{
return true;
} int iterations = (int)Math.Ceiling((double)count1 / sizeof(Int64));
for (int i = ; 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 = ;
while (bytesRead < buffer.Length)
{
int read = await stream.ReadAsync(buffer, bytesRead, buffer.Length - bytesRead).ConfigureAwait(false);
if (read == )
{
// Reached end of stream.
return bytesRead;
} bytesRead += read;
} return bytesRead;
} private static async Task<bool> StreamsContentsAreEqualAsync(Stream stream1, Stream stream2)
{
const int bufferSize = * 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 == )
{
return true;
} int iterations = (int)Math.Ceiling((double)count1 / sizeof(Int64));
for (int i = ; i < iterations; i++)
{
if (BitConverter.ToInt64(buffer1, i * sizeof(Int64)) != BitConverter.ToInt64(buffer2, i * sizeof(Int64)))
{
return false;
}
}
}
}
}
}
谢谢浏览!
怎样用 C# 快速比较 2 个文件是否是相同的文件?的更多相关文章
- 九、将cs文件快速的转换成可执行文件和响应文件(配置编译开关的文件)
1.将包含多个类型的源代码文件转换为可以部署的文件.有如下Program.cs的文件,代码如下: public sealed class Program { public static void Ma ...
- BAT 快速删除CVS文件和拷贝最近修改文件的目录结构
相信大家在操作大量文件的的时候,经常会遇到一些手动很难操作的情况 比如有CVS版本控制下每个文件夹下都有一个CVS文件夹,一个个手工删除肯定很费劲,我们都是懒人,还是用工具解决吧.不用重新写程序,直接 ...
- php快速无限遍历递归文件夹目录、子文件,支持绝对路径和相对路径,支持返回生成数组
支持无限极遍历子文件及文件夹,支持绝对路径和相对路径! 函数说明:array glob ( string $pattern [, int $flags ] )功能:寻找与模式匹配的文件路径,返回包含匹 ...
- Linux磁盘管理之元数据、文件和目录、链接文件03
一.存储设备分区简述 文件系统最终目的是把大量数据有组织的放入持久性的存储设备,如硬盘.硬盘存储能力具有持久性,不会因为断电而消失,存储量大,但读取速度慢.操作系统读取硬盘的时候,不会一个一个扇区读取 ...
- 《Java核心技术卷二》笔记(二)文件操作和内存映射文件
文件操作 上一篇已经总结了流操作,其中也包括文件的读写.文件系统除了读写以为还有很多其他的操作,如复制.移动.删除.目录浏览.属性读写等.在Java7之前,一直使用File类用于文件的操作.Java7 ...
- 镜像文件、光盘、iso文件、启动盘
刚入大学,有一门计算机硬件维修课程,韩国彬老师(学生们公认的好老师).当时韩老师教给了我们好多实用的好东西,例如装系统,做镜像文件,装虚拟机,ghost版本系统,计算机组装等等.由于高中刚刚过度到大学 ...
- 微软BI 之SSIS 系列 - 在 SSIS 中将指定目录下的所有文件分类输出到不同文件夹
开篇介绍 比如有这样的一个需求,旧的一个业务系统通常将产出的文件输出到同一个指定的目录下的不同子目录,输出的文件类型有 XML,EXCEL, TXT 这些不同后缀的文件.现在需要在 SSIS 中将它们 ...
- 使用visual studio把xsd文件转成xml格式文件
使用visual studio把xsd文件转成xml格式文件 最近一段时间都在做Amazon的mws api的对接工作,mws api的描述文件都是使用的xsd文件来进行的,之前确实也没有接触过,也花 ...
- [Erlang06]在Erlang shell怎么在目录A下编译目录B下的文件,并把生成文件统一放置目录C?
问题描述: 我们想快速测试一个小功能,第一个反应就是打开Erl shell 直接输入,但是当想测试一个复杂的函数时,一般会写成一个*.erl文件,然后在shell下: cd(FileDir). c(F ...
- Facebook图片存储系统Haystack——存小文件,本质上是将多个小文件合并为一个大文件来降低io次数,meta data里存偏移量
转自:http://yanyiwu.com/work/2015/01/04/Haystack.html 一篇14页的论文Facebook-Haystack, 看完之后我的印象里就四句话: 因为[传统文 ...
随机推荐
- 练手WPF(一)——模拟时钟与数字时钟的制作(中)
今天接着制作数字时钟 数字时钟主要用到Path控件,主要用于定义数字笔划的形状. (1)添加一个DigitLine类 数字时钟的数字8由7笔组成,看如下定义的字段字符串数组PathDatas,每个st ...
- Java生鲜电商平台-你应该保留的一些学习态度与学习方法
Java生鲜电商平台-你应该保留的一些学习态度与学习方法 说明:Java开源生鲜电商平台这一类学习课程系列已经初步接近了尾声,那么作为学习生鲜电商B2B2C电商的你,应该有一个什么样子的学习态度与学习 ...
- 高强度学习训练第十一天总结:Class文件结构(二)
常量池 可以理解为Class文件之中的资源仓库,他是Class文件结构中与其他项目关联最多的数据类型,也是占用Class文件空间最大的数据项目之一 访问标志 在常量池结束后,紧接着的俩个字节代表访问标 ...
- 仅用StoryBoard布局实现按钮的均匀分布
今天在做登录界面时设计的需求是,登录和取消按钮左右对称均匀分布,按钮大小不变如图 屏幕宽度变化时按钮宽度不变,三个间距相等并且随屏幕变化而变化,简单的说就是按钮均匀分布,在网上查了一些资料,弄得比较乱 ...
- [b0003] 总览:Hadoop 个人学习路线进展
3. Spark 搭建 过 1.1 搭建伪分布式2.0.1 ok 2016-10-23 耗时 2h ref [0006] Spark 2.0.1 伪分布式搭建练手 后续: 1.2 分布 ...
- 在PyCharm中打开文件的位置
选中文件,右键选择 Show in Explorer (在资源管理器中显示) 只需要路径时,选择第四个Copy Path ,会复制文件的路径
- [Go] 并发imap收信
并发数太大会直接死,这里有时候需要多试几次 package main import ( "flag" "fmt" "io/ioutil" & ...
- 免密码登录postgresql
如果在当前shell 下,如果设定 export PGPASSWORD='postgres密码' 环境变量,可以不用每次执行sql 语句或者导入一个sql 文件都输入一次密码的麻烦了.
- node.js是用来做什么的?这是我看到最好的解释了
一种JavaScript的运行环境,能够使得JavaScript脱离浏览器运行. 参考链接:https://www.cnblogs.com/suhaihong/p/6598308.html https ...
- 动态设置html的font-size值
PC端 (function () { function setRootFontSize() { let rem, rootWidth; let rootHtml = document.document ...