c# hashcode compare file content (hash码比对文件内容)
1、使用System.security.Cryptography.HashAlgorithm类为每个文件生成一个哈希码,然后比较两个哈希码是否一致。
FileInfo.Exists:获取指定文件是否存在;
FileInfo.Name,FileInfo.Extensioin:获取文件的名称和扩展名;
FileInfo.FullName:获取文件的全限定名称(完整路径);
FileInfo.Directory:获取文件所在目录,返回类型为DirectoryInfo;
FileInfo.DirectoryName:获取文件所在目录的路径(完整路径);
FileInfo.Length:获取文件的大小(字节数)
FileInfo.IsReadOnly:获取文件是否只读;
FileInfo.Attributes:获取或设置指定文件的属性,返回类型为FileAttributes枚举,可以是多个值的组合;
FileInfo.CreationTime、FileInfo.LastAccessTime、FileInfo.LastWriteTime:分别用于获取文件的创建时间、访问时间、修改时间;
//获取文件hashcode信息 public static Tuple<int,string> GetFileHashCodeInfo(Stream stream) { if (stream == null || stream.Length == 0) return new Tuple<int, string>(0, ""); var hash = System.Security.Cryptography.HashAlgorithm.Create(); //hash算法一般是返回20个元素的数组 byte[] hashByte = hash.ComputeHash(stream); //这里用一个元组的目的是字符串比对耗时,可先通过hashByte相加或者增量相加(取倍数,取平方和,取序号倍乘等)比较,相等再比较hashcode字符串 return new Tuple<int, string>(hashByte.Select(q => (int)q).Sum(),BitConverter.ToString(hashByte)); } public static void CompareFile() { string p_1 = @"E:\readme_1.txt"; string p_2 = @"E:\readme_2.txt"; var stream_1 = new System.IO.FileStream(p_1, System.IO.FileMode.Open); var hash_1=GetFileHashCodeInfo(stream_1 ); stream_1.Close(); //计算第二个文件的哈希值 var stream_2 = new System.IO.FileStream(p_2, System.IO.FileMode.Open); var hash_2=GetFileHashCodeInfo(stream_2 ); stream_2.Close(); if(hash_1.Item1==hash_2.Item1) { if(hash_1.Item2==hash_2.Item2) Console.WriteLine("两个文件相等"); else Console.WriteLine("两个文件不等"); } else Console.WriteLine("两个文件不等"); }
mvc上传文件的时候,我们就可以用以上的思路来去重了:
前端(上传文件用默认的input type:file,上传借用框架:https://github.com/carlcarl/AjaxFileUpload/blob/master/ajaxfileupload.js
以及http://www.oschina.net/code/snippet_105637_50057):
注:今天调试过程中发现一个问题,就是作为文件域(<input type="file">)必须要有name属性,如果没有name属性,上传之后服务器是获取不到图片的。如:正确的写法是<input type="file" id="file1" name="file1" />
<!--Dom标签--> <tr> <td class="title">函件图片:</td> <td ><input type = "file" id="file1" accept="image/png,image/gif,image/tiff,image/jpeg" style="min-width:400px;" /></td> </tr> <tr> <td></td> <td> <img id = "image1" src="#" style="max-width:500px;" /> </td> </tr>
<script>
var file = $("#file1")
file.after(file.clone().val(""));
//清空已选择的文件内容,对一个文件域(input type=”file”)使用了验证后,我们总会希望把文件域中的值给清空了(否则错误的文件仍然会被提交),而在IE中,安全设置的原因,是不允许更改文件域的值的(也就是不能使用val(''))
file.remove();
//选中文件后就前台展示出图片信息
$('#file1').on('change', function () {
var file = this.files[0];
if (this.files && file)
{
var reader = new FileReader();
reader.onload = function(e) {
$('#image1').attr('src', e.target.result);
}
reader.readAsDataURL(file);
}
});
$('#image1').attr('src', '');
$.ajaxFileUpload({
type: 'post',
url: myurl,
secureuri: false,
fileElementId: 'file1',
dataType: 'json',
data: { memo: memo},
success: function(data, status) {
},
error(xhr, status, error){
}
});
</script>
后端:
文件hashcode信息库

mvc action方法
HttpFileCollection hfc = System.Web.HttpContext.Current.Request.Files; // HttpFileCollectionBase hfc = Request.Files; if (hfc.Count !=1 ) { throw new Exception("操作错误,请重新尝试!"); } if (hfc[0].InputStream == null || hfc[0].InputStream.Length == 0) { throw new Exception("操作错误,请重新尝试!"); } Tuple<int,string> hashInfo = ExcelUtils.GetFileHashCodeInfo(hfc[0].InputStream); //通过HashCodeSum读取库里数据,然后比对HashCode值 var list = logic.GetImageInfoList(hashInfo.Item1); string imagePath; if (list == null || !list.Any(q => q.ImageHashCode == hashInfo.Item2)) { var basePath = "/Image"; string fileName = $"{ Guid.NewGuid().ToString() }.{ Path.GetExtension(hfc[0].FileName)}"; string filePath = $"{Server.MapPath(basePath)}\\{fileName}"; hfc[0].InputStream.Position = 0; byte[] buffer = new byte[hfc[0].InputStream.Length]; hfc[0].InputStream.Read(buffer, 0, (int)hfc[0].InputStream.Length); System.IO.File.WriteAllBytes(filePath, buffer); imagePath = $"{basePath}/{fileName}"; logic.AddImageInfo(new ImageInfo() { ImageHashCode = hashInfo.Item2, ImageHashSum = hashInfo.Item1, ImagePath = imagePath }); } else imagePath = list.Where(q => q.ImageHashCode == hashInfo.Item2).First().ImagePath;
备注,$.ajaxFileUpload方法说明:
ajaxFileUpload是一个异步上传文件的jQuery插件
传一个不知道什么版本的上来,以后不用到处找了。
语法:$.ajaxFileUpload([options])
options参数说明:
1、url 上传处理程序地址。
2,fileElementId 需要上传的文件域的ID,即<input type="file">的ID。
3,secureuri 是否启用安全提交,默认为false。
4,dataType 服务器返回的数据类型。可以为xml,script,json,html。如果不填写,jQuery会自动判断。
5,success 提交成功后自动执行的处理函数,参数data就是服务器返回的数据。
6,error 提交失败自动执行的处理函数。
7,data 自定义参数。这个东西比较有用,当有数据是与上传的图片相关的时候,这个东西就要用到了。
8, type 当要提交自定义参数时,这个参数要设置成post
错误提示:
1,SyntaxError: missing ; before statement错误
如果出现这个错误就需要检查url路径是否可以访问
2,SyntaxError: syntax error错误
如果出现这个错误就需要检查处理提交操作的服务器后台处理程序是否存在语法错误
3,SyntaxError: invalid property id错误
如果出现这个错误就需要检查文本域属性ID是否存在
4,SyntaxError: missing } in XML expression错误
如果出现这个错误就需要检查文件name是否一致或不存在
5,其它自定义错误
大家可使用变量$error直接打印的方法检查各参数是否正确,比起上面这些无效的错误提示还是方便很多。
备注:上传大文件,超过4M时候,报:System.Web.HttpException: 超过了最大请求长度! 解决办法如下:
修改web.config文件
<configuration>
<system.web>
<httpRuntime maxRequestLength="10000" /><!--10M-->
</system.web>
<configuration>

浙公网安备 33010602011771号