Параўнанне двух файлаў у C #

Я хачу, каб параўнаць два файла ў C# і паглядзець, калі яны розныя. Яны маюць тыя ж імёны файлаў і яны сапраўды такога ж памеру, калі розныя. Мне было проста цікава, калі ёсць хуткі спосаб зрабіць гэта без неабходнасці ўручную пайсці і прачытаць файл.

дзякуй

14
Лот меркаванняў па гэтым аднаму, ТОЗУ. Не забудзьцеся прачытаць каментары, каб пераканацца, што вы робіце тое, што лепш за ўсё падыходзіць для вашага выпадку выкарыстання. Поспехаў!
дададзена аўтар Random, крыніца
@Boo: О <я> тыя паказвае вы 100% правільна.
дададзена аўтар jason, крыніца
Было б карысна ведаць выпадак выкарыстання раней. Ва ўсякім выпадку .. вы можаце паглядзець у загаловак ETag HTTP. Хай вэб-сервер рабіць усю працу.
дададзена аўтар Sam Axe, крыніца
Прывітання хлопцы, шмат правільных адказаў. Я, верагодна, выкарыстоўваць байты параўнання байт. Я растлумачу сваю сітуацыю больш дэталёва: Я загрузка файлаў з сайта кожныя 5 хвілін, і праверыць, каб убачыць, калі файл адрозніваецца ад папярэдняга загружанага файла. Ён будзе адрознівацца адзін раз у дзень, калі я спыніць загрузку файлаў. Як параўнання будзе такі ж большую частку часу я думаю, што байт у параўнанні байта будзе лепш. Дзякуй зноў!
дададзена аўтар Toz, крыніца

7 адказы

Depending on how far you're looking to take it, you can take a look at Diff.NET

Вось простая функцыя параўнання файлаў:

// This method accepts two strings the represent two files to 
// compare. A return value of 0 indicates that the contents of the files
// are the same. A return value of any other value indicates that the 
// files are not the same.
private bool FileCompare(string file1, string file2)
{
     int file1byte;
     int file2byte;
     FileStream fs1;
     FileStream fs2;

    //Determine if the same file was referenced two times.
     if (file1 == file2)
     {
         //Return true to indicate that the files are the same.
          return true;
     }

    //Open the two files.
     fs1 = new FileStream(file1, FileMode.Open, FileAccess.Read);
     fs2 = new FileStream(file2, FileMode.Open, FileAccess.Read);

    //Check the file sizes. If they are not the same, the files 
       //are not the same.
     if (fs1.Length != fs2.Length)
     {
         //Close the file
          fs1.Close();
          fs2.Close();

         //Return false to indicate files are different
          return false;
     }

    //Read and compare a byte from each file until either a
    //non-matching set of bytes is found or until the end of
    //file1 is reached.
     do 
     {
         //Read one byte from each file.
          file1byte = fs1.ReadByte();
          file2byte = fs2.ReadByte();
     }
     while ((file1byte == file2byte) && (file1byte != -1));

    //Close the files.
     fs1.Close();
     fs2.Close();

    //Return the success of the comparison. "file1byte" is 
    //equal to "file2byte" at this point only if the files are 
    //the same.
     return ((file1byte - file2byte) == 0);
}
26
дададзена
Любая прычына, каб выкарыстоўваць (file1byte - file2byte) == 0 замест проста file1byte == file2byte ?
дададзена аўтар Juan, крыніца
На гэтым праклятым OS X вы не можаце бачыць увесь код <Ь> і няма паласы прагорткі, што дазваляе выказаць здагадку, што ёсць больш коды.
дададзена аўтар Andrei Rînea, крыніца
Гэта не можа працаваць, калі файл быў зменены толькі адзін знак. Паток даўжыня будзе такі ж, але змест не тое ж самае. Гэта не дзейнічае!
дададзена аўтар Daniel Peñalba, крыніца
На жаль, я не хачу здацца грубым :-) Пытанне сказаў: «Яны маюць тыя ж імёны файлаў і яны сапраўды такія ж памер, калі розныя". Такім чынам, гэты падыход да памылак. Мы распрацоўваем сістэмы кіравання версіямі і гэты выгляд рэалізацыі можа прывесці да катастрофы ў базе дадзеных SCM.
дададзена аўтар Daniel Peñalba, крыніца
Выкарыстоўвайце болей , выкарыстоўваючы !
дададзена аўтар binki, крыніца
Гэта было на самай справе выцягнуў з сайта Microsoft. Гэта робіць параўнанне роўнасці, параўнанне даўжыні і параўнанне байт у байт. Я думаю, што вы маглі б быць няправільна пра гэта.
дададзена аўтар James Johnson, крыніца
Я б сказаў, што код правільны.
дададзена аўтар Stabledog, крыніца
Код правільны, але вы павінны пракруціць ўніз, каб убачыць біт, які робіць байт у параўнанні байта. Я мяркую, што Данііл не пракручваць ўніз.
дададзена аўтар Dave Knight, крыніца
@Daniel: прабачце ўваскрэсіць стары пост, але вы можаце клапаціцца, каб растлумачыць, што гэта актуальная праблема з кодам? Здаецца, добра да мяне, ён правярае памер файла, а затым побайтно. Як мог адзін розніца сімвалаў пазбегнуць праверкі? Gracias!
дададзена аўтар Evaldas Bieliūnas, крыніца
<Р> Мне было проста цікава, калі ёсць хуткі спосаб зрабіць гэта без неабходнасці ўручную пайсці і прачытаць файл.

Не зусім.

If the files came with hashes, you could compare the hashes, and if they are different you can conclude the files are different (same hashes, however, does not mean the files are the same and so you will still have to do a byte by byte comparison).

Аднак, хэшы не выкарыстоўваць усе байты ў файле, таму незалежна ад таго, што вы ў нейкі момант павінны прачытаць файлы побайтно. І на самай справе, проста прамыя байты параўнання байт будуць хутчэй, чым вылічэнне хэша. Гэта адбываецца таму, што хэш счытвае ўсе байты гэтак жа, як параўнанне байт у байтах робяць, але хэш зрабіць некаторыя іншыя вылічэнні, якія дадаюць час. Акрамя таго, байт за байт параўнанне можа завяршыць на ранняй стадыі першай пары няроўных байт.

Нарэшце, вы не можаце пазбегнуць неабходнасці чытання байт у байт. Калі хэшы супадаюць, гэта не азначае, што файлы аднолькавыя. У гэтым выпадку вам усё роўна прыйдзецца параўноўваць байт за байт.

18
дададзена
Не маглі б вы растлумачыць, чаму вы павінны параўнаць байт за байт, калі хэшы аднолькавыя? Чаму б хэшы быць такім жа, калі дадзеныя адрозніваюцца?
дададзена аўтар scottm, крыніца
Я не downvote гэты, я не ведаю, хто робіць усё гэта, але я не згодны з нагоды хэшавання. У яго ёсць сапраўднае выкарыстанне, калі хэш захоўваюцца для параўнання ў будучыні. Я зрабіў гэта з файламі малюнкаў, а хуткасць дзіўная.
дададзена аўтар Random, крыніца
@scottm: Паколькі няроўныя файлы могуць мець аднолькавыя хэшы. Гэта прынцып закуток. Скажам, мы выкарыстоўваем md5. md5 вырабляе 128-бітны хэш файла. Такім чынам, існуе 2 ^ 128 розных хэшаў. Ёсьць нашмат больш, чым 2 ^ 128 розных файлаў. Таму, так як мы адлюстраванне прасторы з больш чым 2 ^ 128 розных значэнняў у прасторы з 2 ^ 128 значэнняў, павінны быць сутыкнення. Хэш не зьяўляюцца ўнікальнымі подпісамі.
дададзена аўтар jason, крыніца
@svick: Але гэта <я> дакладна адзін з мэтаў гнюса з дапамогай SHA-1! Гэта выявіць разбэшчанасьці ў сховішча, магчыма зламыснікамі.
дададзена аўтар jason, крыніца
@Downvoters: Тры downvotes? Нічога сабе.
дададзена аўтар jason, крыніца
@svick: Вядома мярзотнік абапіраецца на гэтую здагадку, але ён схільны да хэш сутыкнення. Гэта праблема для гнюса.
дададзена аўтар jason, крыніца
@Random: А я казаў, што вы можаце выкарыстоўваць хэш заключыць файлы няроўныя, калі хэш роўныя, і гэта выгадна, калі яны папярэдне вылічаныя. Калі яны не з'яўляюцца папярэдне вылічаным, яны не хутчэй, і калі яны роўныя, то ўсё роўна прыйдзецца ісці байты за байт.
дададзена аўтар jason, крыніца
Downvoter: Растлумачце.
дададзена аўтар jason, крыніца
@Jason, я думаю, што гэта патэнцыйная праблема, але гэта не праблема ў праксісу. Калі вы ведаеце, што вам не прыйдзецца атакуючым спрабуюць зламаць хэш, вам не прыйдзецца турбавацца пра сутыкненні.
дададзена аўтар svick, крыніца
Калі ў вас ёсць аднолькавыя хэшы, вы можаце быць цалкам упэўнены, што файлы аднолькавыя. Вы маеце рацыю, што вам трэба параўнаць файлы побайтно быць абсалютна ўпэўнены (і асабліва, калі ваша бяспека залежыць ад гэтага). Але некаторыя сістэмы, як мярзотнік спадзявацца на тое, што два розных файла з аднолькавым хэш не будзе адлюстроўвацца ўнутры сістэмы. Вядома, усё гэта мяркуе добрую хэш, а не нешта накшталт GetHashCode() .
дададзена аўтар svick, крыніца

Ну, я не ўпэўнены, калі вы можаце ў файле пісаць часовыя пазнакі. Калі няма, то ваш унікальны варыянт, параўноўвае ўтрыманне файлаў.

Просты падыход параўноўвае файлы байт-на-байт, але калі вы збіраецеся параўнанне файла некалькі разоў з іншымі, вы можаце вылічыць хэш файлаў і параўнаць яго.

Наступны фрагмент кода паказвае, як вы можаце гэта зрабіць:

    public static string CalcHashCode(string filename)
    {
        FileStream stream = new FileStream(
            filename,
            System.IO.FileMode.Open,
            System.IO.FileAccess.Read,
            System.IO.FileShare.ReadWrite);

        try
        {
            return CalcHashCode(stream);
        }
        finally
        {
            stream.Close();
        }
    }

    public static string CalcHashCode(FileStream file)
    {
        MD5CryptoServiceProvider md5Provider = new MD5CryptoServiceProvider();
        Byte[] hash = md5Provider.ComputeHash(file);
        return Convert.ToBase64String(hash);
    }

Калі вы збіраецеся параўнаць файл з іншымі больш, што адзін раз, вы можаце захаваць файл хэш і параўнаць яго. Для аднаго параўнання, параўнанне байт у байт лепш. Вы павінны таксама пералічваць хэш пры змене файла, але калі вы збіраецеся рабіць масіўныя параўнання (больш чым адзін раз), я рэкамендую выкарыстоўваць хэш-падыход.

4
дададзена
Падобна на тое, мы гаворым пра тое, ці з'яўляецца хэш а <я> ідэальны хэш ці не. Алгарытм хэшавання MD5 з'яўляецца <я> не дасканалыя, таму Джэйсан мае рацыю - ёсць магчымасць хэш сутыкнення.
дададзена аўтар Ben, крыніца
@Jason: Гэта толькі абмеркаванне прадукцыйнасці. У нашым выпадку мы параўноўваем дыск дрэва да дрэва аддаленага дыска. Мы папярэдне вылічаныя хэшаў ў абодвух дыска і пульта дыстанцыйнага кіравання, так што наша задача толькі параўнаць пару hashses на файл. А таксама пералічыць хэш пры змене файла. Без сумневу, гэта лепшы спосаб зрабіць гэта.
дададзена аўтар Daniel Peñalba, крыніца
@Jason: Ідэя заключаецца ў тым захоўваць хэш файла ў любым месцы і скарыстацца пра гэта. Так, вядома, рабіць байт у байт параўнання лепш, калі вы збіраецеся вылічыць толькі адзін раз.
дададзена аўтар Daniel Peñalba, крыніца
@Daniel Peñalba: Але вам усё роўна прыйдзецца ісці байт за байт, калі хэшы роўныя быць 100% упэўненыя, што файлы аднолькавыя.
дададзена аўтар jason, крыніца
@svick: Так. Байты ў байтах могуць заканчвацца раней, хеши ўсё яшчэ прачытаць усё змесціва так жа, як байты ў байтах могуць, і калі хэш роўныя, мы павінны ісці байты за байт у любым выпадку.
дададзена аўтар jason, крыніца
Няма! Вы <б> STILL павінны параўноўваць побайтно, калі хэшы роўныя. І калі хэшы няроўныя, гэта хутчэй проста байт у байт, так як ён можа спыніць рана на першым няроўнай пары байтаў, але хэш павінен прайсці ўвесь шлях да канца файла! Argh!
дададзена аўтар jason, крыніца
Для запісу, два асобных файлаў і з тым жа імем файла і даўжынёй амаль напэўна (амаль) павінны мець два розных часовых метак. Калі нічога іншага, гэта заняло б па меншай меры пару милисекунд напісаць другую копію.
дададзена аўтар AllenG, крыніца
Калі ў вас ёсць абодва файл даступны, я думаю, што вылічэнне хэша як будзе на самой справе больш павольна, чым параўнанне іх непасрэдна.
дададзена аўтар svick, крыніца

Калі імёны файлаў супадаюць, а памеры файлаў супадаюць, то, няма, няма ніякага спосабу даведацца, калі яны маюць рознае ўтрыманне без вывучэння зместу.

3
дададзена
Адказ на гэтае пытанне, а лаканічныя, (у цяперашні час) адзіны правільны адказ у гэтай тэме. Гэта не павінна быць downvoted.
дададзена аўтар jason, крыніца
Я з Джэйсанам: Пракаментуйце, калі ласка, калі вы ўніз галасаванне.
дададзена аўтар AllenG, крыніца

прайсці кожны файл патоку праз Hasher MD5 і параўнаць хэшы.

2
дададзена
@Jason, ёсць таксама праблема, калі файлы не аднолькавага памеру. Я ведаю, што пытанне кажа, што файлы, але пры ўмове, што яны не могуць быць, мы можам выключыць праверку таго, што. Разлічаныя хэшы будуць мець аднолькавы памер.
дададзена аўтар Random, крыніца
@Boo: Дзіўна. ОП хоча ведаць, калі файлы аднолькавыя, няма, калі яны, верагодна, тое ж самае.
дададзена аўтар jason, крыніца
@L. B: Параўнанне двух файлаў адрозненняў ня крыптаграфічныя прыкладанне. Мы не спрабуем праверыць, калі два файла <я>, верагодна, роўныя, а калі яны з'яўляюцца роўныя.
дададзена аўтар jason, крыніца
@Random: Я не разумею, пра што вы кажаце.
дададзена аўтар jason, крыніца
@ L.B: Тая ж праблема ставіцца да любога алгарытму хэшавання. ANY. Хэш прыняць вялікая прастора і згарнуць яго ў невялікім прасторы. КОЖНЫ алгарытм хэшавання будзе мець сутыкнення, і многія з іх.
дададзена аўтар jason, крыніца
Hex коды d131dd02c5e6eec4693d9a0698aff95c 2fcab58712467eab4004583eb8fb7f89 55ad340609f4b30283e488832571415a 085125e8f7cdc99fd91dbdf280373c5b d8823e3156348f5bae6dacd436c919c6 dd53e2b487da03fd02396306d248cda0 e99f33420f577ee8ce54b67080a80d1e c69821bcb6a8839396f9652b6ff72a70 і d131dd02c5e6eec4693d9a0698aff95c 2fcab50712467eab4004583eb8fb7f89 55ad340609f4b30283e4888325f1415a 085125e8f7cdc99fd91dbd7280373c5b d8823e3156348f5bae6dacd436c919c6 dd53e23487da03fd02396306d248cda0 e99f33420f577ee8ce54b67080280d1e c69821bcb6a8839396f965ab6ff72a70 маюць аднолькавы хэш md5. Яны не роўныя.
дададзена аўтар jason, крыніца
Не, гэта азначае, што яны маюць адзін і той жа хэш. Гэта НЕ «азначае, што файлы аднолькавыя.»
дададзена аўтар jason, крыніца
Вы не звярталі ўвагі: вы STILL павінны зрабіць байт у параўнанні байта, калі хэшы роўныя. Выкарыстанне Хэшаў ня менш працы, то <б> MORE праца, таму што вы павінны напісаць байт у байт параўнання і код для выкарыстання алгарытму хэшавання, і логіку, каб выкарыстоўваць байт за байт, калі хэшы роўныя.
дададзена аўтар jason, крыніца
Але калі хэшы роўныя, вам усё роўна прыйдзецца ўручную чытаць файлы і параўноўваць побайтно заключыць яны фактычна роўныя. Гэта НЕ менш працы. Вы не можаце пазбегнуць, то трэба для байта ў параўнанні байт.
дададзена аўтар jason, крыніца
Гэта не хутчэй, чым проста параўнанне побайтно і вам усё роўна прыйдзецца ісці побайтно, калі хэшы роўныя!
дададзена аўтар jason, крыніца
Хто будзе выкарыстоўваць MD5?
дададзена аўтар L.B, крыніца
@Jason, я ведаю, вы маеце рацыю ў тэорыі, але разлічваць большасць крыптаграфічных прыкладанняў на «унікальнасці» сучаснага хэш alg.s. Я хацеў бы зрабіць тое ж самае для параўнання файлаў
дададзена аўтар L.B, крыніца
Гэты размова скончаны.
дададзена аўтар Sam Axe, крыніца
Менш праграмавання працы. Працэсары Арент sentiant (пакуль), так што хто клапоціцца, калі гэта мае дачыненне да якой-небудзь дадатковай працы. Сучасныя працэсары досыць хутка, што вы не заўважыце дадатковую працу, калі вы не робіце іх шмат у кароткі прамежак часу. Але ОП не пазначана, што гэта мела месца.
дададзена аўтар Sam Axe, крыніца
@Jason: якая частка «у межах статыстычнай верагоднасці» збівае з толку? Вядома, ёсць сутыкнення. Liklihood сутыкнення ў рэальнай сітуацыі знікаюча малы. Гэта не лабараторыя.
дададзена аўтар Sam Axe, крыніца
Не. Там няма ніякіх падставаў, каб зрабіць байт у байт параўнання ўручную, калі хэшы роўныя. Роўныя хэш (у межах статыстычнай верагоднасці) азначае, што файлы аднолькавыя.
дададзена аўтар Sam Axe, крыніца
Яго менш працы. І ОП expessed жадання пазбегнуць рабіць само параўнанне байт.
дададзена аўтар Sam Axe, крыніца

Калі яны не выконваюцца файлы, то выкарыстоўвайце інструмент параўнання, як KDiff або WinMerge. На ім будуць яны былі розныя.

http://kdiff3.sourceforge.net/

http://winmerge.org/

2
дададзена
Пытанне аб тым, як праграмна параўнаць два файла ў .net. Аскер піша код у C# і мае патрэбу ў праграме, што ён піша для параўнання двух файлаў. Ён, верагодна, не зацікаўленыя ў shellout або інструмент з графічным інтэрфейсам.
дададзена аўтар binki, крыніца

Прачытаць файл ў струмень, а затым хэш патоку. Гэта павінна даць вам дакладны вынік для параўнання.

byte[] fileHash1, fileHash2;

using (SHA256Managed sha = new SHA256Managed())
{
    fileHash1 = sha.ComputeHash(streamforfile1);
    fileHash2 = sha.ComputeHash(streamforfile2);
}

for (int i = 0; (i < fileHash1.Length) && (i < fileHash2.Length); i++)
    {
        if (fileHash[i] != fileHash2[i]) 
        { 
             //files are not the same
             break; 
        }
    }
0
дададзена