내용이 다른 경우 이진 파일을 교체하고 싶습니다.C#에서 이진 파일을 비교할 수 있습니까?
그래서 이진 파일을 비 직렬화 할 필요없이 비교할 수 있어야합니다.
이것이 가능합니까?
이진 포맷터를 사용하여 파일을 저장했습니다.
내용이 다른 경우 이진 파일을 교체하고 싶습니다.C#에서 이진 파일을 비교할 수 있습니까?
그래서 이진 파일을 비 직렬화 할 필요없이 비교할 수 있어야합니다.
이것이 가능합니까?
이진 포맷터를 사용하여 파일을 저장했습니다.
예. 각 파일 데이터 세트에 대해 MD5 또는 SHA1 해시를 생성 한 다음 비교할 수 있습니다.
샘플 코드 (오류 명확성을 위해 제거 확인) :
public bool CompareFiles(string filePath1, string filePath2)
{
FileInfo info1 = new FileInfo(filePath1);
FileInfo info2 = new FileInfo(filePath2);
byte[] data1 = new byte[info1.Length]
byte[] data2 = new byte[info2.Length];
FileStream fs1 = new FileStream(filePath1, FileMode.Open);
FileStream fs2 = new FileStream(filePath2, FileMode.Open);
fs1.Read(data1, 0, info1.Length);
fs2.Read(data2, 0, info2.Length);
fs1.Dispose();
fs2.Dispose();
SHA1 sha = new SHA1CryptoServiceProvider();
byte[] hash1 = sha.ComputeHash(data1);
byte[] hash2 = sha.ComputeHash(data2);
// c# 2 or less: you need to compare the hash bytes yourself
// c# 3.5/4
bool result = hash1.SequenceEqual(hash2);
return result;
}
두 개의 파일 만 있으면 바이트를 직접 비교하면 첫 번째 차이에서 빠져 나올 수 있지만 해시를 계산할 경우 매우 비쌀 수있는 전체 파일을 읽어야합니다. – luke
둘 다 전체 파일을 읽지 않습니까? 요점은 무엇입니까? 물론 하나의 파일을 여러 번 비교할 때 해시를 계산하는 것이 유용 할 수 있지만 그럴 수는 없습니다. –
해시 계산은 실제로 더 나쁩니다. 바이트 단위로 비교할 때 처음 몇 바이트 이후에 멈출 수 있습니다 (다른 경우). –
예 가능합니다.
파일을 읽으려면 파일을 읽어야합니다.
의사 코드는 다음과 같습니다 스트림으로
동일한 파일을 여러 파일과 비교해야하는 경우 첫 번째 파일의 해시를 계산하는 것이 좋습니다. 그런 다음 다른 파일 각각의 해시를 계산하고 해시를 비교하십시오.
나는 마지막 단계를 약간 수정했다 : "서로 다르거 나 파일 끝에 도달 할 때까지 반복한다."첫 번째 바이트가 다른 경우 끝까지 계속 가고 싶지는 않을 것이다. –
나는 OP가 직렬화 된 버전에 따라 클래스가 변경되었는지 감지하려고한다고 생각합니다. 필자는 BinaryFormatter가 '동일한'클래스가 정확히 동일한 바이트를 가질 것이라고 보장하지 않기 때문에 파일 비교가 불가능하다고 생각합니다. –
@ Neil, 물론 맞습니다. 나는 그것이 명백했다라고 생각했다 - 지금 대답을 정정했다 :-) – driis
byte[] myFile = File.ReadAllBytes(pathToFile);
그런 다음 반복하십시오. 파일이 클 경우 속도가 느려질 수 있습니다.
아마 당신은 당신이 파일의 바이너리 내용을 읽고 당신이 얻을 바이트를 비교할 수있는 파일의 MD5 해시 알고리즘
을 찾아야한다. 파일을 읽으려면 ReadAllBytes
(파일 크기가 적당하고 메모리에 편안하게 맞는지 확인) 또는 FileStream
을 사용하고 두 파일의 데이터 청크를 읽을 수 있습니다.
다음과 같을 수 버퍼를 사용하여 접근 방식의 구조 :
byte[] buffer1 = new byte[1024], buffer2 = new byte[1024];
using(var fs1 = new FileStream(firstFile, FileMode.Open, FileAccess.Read)
using(var fs2 = new FileStream(secondFile, FileMode.Open, FileAccess.Read)
{
// Use: fs.Read(buffer1, 0, 1024) to repeatedly read 1kb of data
// from both fs1 and fs2 and compare the content in buffer1 and buffer2
}
어떤 사람들은 해시를 사용하는 것이 좋습니다,하지만 그건 좋은 생각이 아니다 - 파일이 동일한 경우, 당신은 모든 읽기해야합니다 파일로부터의 데이터이므로 해시를 계산하는 것이 모든 데이터를 읽고 비교하는 것보다 효율적이지 않습니다. 그러나 파일이 처음 몇 바이트가 다른 경우 처음 몇 바이트 만 읽어야합니다 (바이트 단위로 비교하는 경우).
해시는 여러 파일 (예 : 각 파일 각각)을 비교하려는 경우에 유용합니다.
다음과 같은 기능이 있습니다. 다른 사람이 바이트 배열을 비교하는 더 좋은 방법을 제공 할 수 없다면.
private static bool CompareFiles(string file1, string file2)
{
var fsFile1 = new System.IO.FileStream(file1, System.IO.FileMode.Open, System.IO.FileAccess.Read);
var fsFile2 = new System.IO.FileStream(file2, System.IO.FileMode.Open, System.IO.FileAccess.Read);
var md5 = new System.Security.Cryptography.MD5Cng();
var md5File1 = md5.ComputeHash(fsFile1);
var md5File2 = md5.ComputeHash(fsFile2);
for (int i = 0; i < md5File1.Length; ++i)
{
if (md5File1[i] != md5File2[i])
return false;
}
return true;
}
당신은 질문을 명확히해야합니다 : 이진 파일을 무엇과 비교하고 있습니까?다른 바이너리 파일입니까, 아니면 파일에 직렬화 할 것인지 안되는 클래스의 메모리 내 인스턴스입니까? –