নেট ব্যবহার করে কীভাবে 2 টি ফাইলের তুলনা করবেন?


136

সাধারণ পন্থাগুলি ফাইলস্ট্রিমের মাধ্যমে বাইনারি পড়ার এবং বাই-বাই বাইটের সাথে তুলনা করার পরামর্শ দেয়।

  • সিআরসি-র মতো চেকসাম তুলনা কি আরও দ্রুত হবে?
  • এমন কোন .NET গ্রন্থাগার রয়েছে যা কোনও ফাইলের জন্য চেকসাম তৈরি করতে পারে?

উত্তর:


117

একটি চেকসাম তুলনা সম্ভবত বাইট বাই বাইটের তুলনায় ধীর হবে।

একটি চেকসাম তৈরি করতে আপনাকে ফাইলের প্রতিটি বাইট লোড করতে হবে এবং এটিতে প্রক্রিয়াজাতকরণ করতে হবে। এরপরে আপনাকে এটি দ্বিতীয় ফাইলটিতে করতে হবে। তুলনা পরীক্ষার চেয়ে প্রক্রিয়াজাতকরণটি প্রায় অবশ্যই ধীর হবে।

চেকসাম তৈরির ক্ষেত্রে: আপনি ক্রিপ্টোগ্রাফি ক্লাসগুলির সাহায্যে এটি সহজেই করতে পারেন। সি # দিয়ে এমডি 5 চেকসাম তৈরির সংক্ষিপ্ত উদাহরণ এখানে ।

তবে, যদি আপনি "পরীক্ষা" বা "বেস" কেসটির চেকসামটি প্রাক-গণনা করতে পারেন তবে একটি চেকসাম দ্রুততর হতে পারে এবং আরও বোধগম্য হতে পারে। আপনার যদি কোনও বিদ্যমান ফাইল থাকে এবং আপনি যদি নতুন ফাইলটি বিদ্যমান ফাইলের সমান হয় কিনা তা পরীক্ষা করে দেখছেন, আপনার "বিদ্যমান" ফাইলটিতে চেকসামের প্রাক-গণনা করার অর্থ কেবলমাত্র একবার ডিস্কআইও করা দরকার, নতুন নথি. এটি সম্ভবত বাইট বাই বাইটের তুলনায় দ্রুত হবে।


30
আপনার ফাইলগুলি কোথায় অবস্থিত তা অ্যাকাউন্টে নেওয়ার বিষয়টি নিশ্চিত করুন। আপনি যদি স্থানীয় ফাইলগুলিকে বিশ্বজুড়ে ব্যাক-আপ অর্ধপথে (বা ভয়ঙ্কর ব্যান্ডউইথের সাথে কোনও নেটওয়ার্কের সাথে) তুলনা করছেন তবে প্রথমে আপনি হ্যাশ দিয়ে ভাল করতে পারেন এবং বাইটস স্ট্রিমটি প্রেরণ না করে নেটওয়ার্কের মাধ্যমে একটি চেকসাম পাঠাতে পারেন better তুলনা করা.
কিম

@ রিডকপসি: আমারও অনুরূপ সমস্যা হচ্ছে, যেহেতু বেশ কয়েকটি বিবরণীর দ্বারা উত্পাদিত ইনপুট / আউটপুট ফাইলগুলি সংরক্ষণ করতে হবে যেগুলিতে প্রচুর নকল রয়েছে বলে মনে করা হচ্ছে। আমি প্রাক্পম্পিউটেড হ্যাশ ব্যবহার করার চিন্তা করেছি, তবে আপনি কি মনে করেন যে আমি যুক্তিসঙ্গতভাবে ধরে নিতে পারি যে যদি 2 (যেমন MD5) হ্যাশ সমান হয় তবে 2 টি ফাইল সমান হয় এবং আরও বাইট-2-বাইট তুলনা এড়ানো যায়? আমি যতদূর জানি এমডি 5 / এসএএএ 1 ইত্যাদির সংঘর্ষগুলি সত্যই সম্ভাবনা কম ...
digEmAll

1
@ ডিজাইমএল-এর সমস্ত সংঘর্ষের সুযোগ কম - আপনি সর্বদা একটি শক্তিশালী হ্যাশ করতে পারেন, যদিও - যেমন: SHA1 এর পরিবর্তে SHA256 ব্যবহার করুন, যা সংঘর্ষের সম্ভাবনা আরও কমিয়ে দেবে।
রিড কোপসি

আপনার উত্তরের জন্য ধন্যবাদ - আমি ঠিক নেট। আমি ধরে নিচ্ছি যে যদি কেউ হ্যাশকোড / চেক সুম কৌশলটি ব্যবহার করে, তবে মূল ফোল্ডারের হ্যাশগুলি অবিচ্ছিন্নভাবে কোথাও সংরক্ষণ করা হবে? কৌতূহলের বাইরে আপনি কীভাবে এটি ডাব্লুপিএফ অ্যাপ্লিকেশনটির জন্য সঞ্চয় করবেন - আপনি কী করবেন? (আমি বর্তমানে এক্সএমএল, পাঠ্য ফাইল বা ডাটাবেসগুলি দেখছি)।
বিকেএসপুরজন

139

সবচেয়ে ধীরতম পদ্ধতিটি হ'ল বাইট বাই দুটি ফাইলের তুলনা করা। আমি যে দ্রুততার সাথে আসতে পেরেছি তা হ'ল একই রকম তুলনা, তবে একবারে এক বাইটের পরিবর্তে আপনি ইন্টার 64 এর আকারের বাইটের অ্যারে ব্যবহার করবেন এবং তারপরে ফলাফলগুলির সংখ্যার তুলনা করুন।

আমি এখানে যা এলাম তা এখানে:

    const int BYTES_TO_READ = sizeof(Int64);

    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;
    }

আমার পরীক্ষায়, আমি প্রায় 3: 1 দ্বারা এই সরল সরল রিডবাইট () দৃশ্যকে ছাপিয়ে দেখতে সক্ষম হয়েছি। ১০০০ রানেরও বেশি গড়ে, আমি এই পদ্ধতিটি 1063ms এ পেয়েছি এবং নীচের পদ্ধতিটি (বাইট তুলনা করে সোজা বাইট) 3031ms এ পেয়েছি। হ্যাশিং প্রায় 865ms গড়ে প্রায় সাব-সেকেন্ডে ফিরে আসে। এই পরীক্ষাটি একটি 100 এমবি ভিডিও ফাইল সহ ছিল।

তুলনার উদ্দেশ্যে, আমি ব্যবহৃত ReadByte এবং হ্যাশিং পদ্ধতি এখানে:

    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;
    }

    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;
    }

1
তুমি আমার জীবনকে সহজ করেছ আপনাকে ধন্যবাদ
30:55 এ 5 এন্ডিন্ডিস

2
@ আনইন্ডিস: সম্পূর্ণতার জন্য, আপনি @ লার্স'র উত্তর এবং @ র্যান্ডমইনসানো এর উত্তর দুটিই পড়তে চাইতে পারেন । খুশী যদিও এত বছর ধরে সাহায্য করেছে! :)
chsh

1
FilesAreEqual_Hashপদ্ধতি থাকা উচিত usingউভয় ফাইল খুব মত স্ট্রীম করে ReadByteপদ্ধতি অন্যথায় এটি উভয় ফাইলগুলিতে স্তব্ধ হয়ে হবে।
ইয়ান মেরার

2
মনে রাখবেন যে FileStream.Read()অনুরোধ করা সংখ্যার চেয়ে কম বাইটস পড়তে পারে। StreamReader.ReadBlock()পরিবর্তে আপনার ব্যবহার করা উচিত ।
প্যালেক

2
ইনট version৪ সংস্করণে যখন স্ট্রিমের দৈর্ঘ্য ইন্ট .৪ এর একাধিক না হয় তবে শেষ পুনরাবৃত্তিটি পূর্ববর্তী পুনরাবৃত্তির ফিলগুলি ব্যবহার করে অসম্পূর্ণ বাইটের সাথে তুলনা করছে (এটিও সমান হওয়া উচিত তাই এটি ভাল)। এছাড়াও যদি স্ট্রিমটির দৈর্ঘ্য আকারের (ইন্ট Int৪) এর চেয়ে কম হয় তবে সি # অ্যারে আরম্ভ করে আরম্ভ করা বাইটগুলি 0 হয়। আইএমও, কোডটির সম্ভবত এই স্বতন্ত্রতাগুলি মন্তব্য করা উচিত।
ক্রোকসেক

46

আপনি যদি না সিদ্ধান্ত নেন আপনি সত্যিই প্রয়োজন পূর্ণ বাইট-বাই-বাইট তুলনা (হ্যাশ এর আলোচনার জন্য অন্যান্য উত্তরগুলি দেখতে), তারপর সহজ সমাধান হল:


• জন্য System.IO.FileInfoদৃষ্টান্ত:

public static bool AreFileContentsEqual(FileInfo fi1, FileInfo fi2) =>
    fi1.Length == fi2.Length &&
    (fi1.Length == 0 || File.ReadAllBytes(fi1.FullName).SequenceEqual(
                        File.ReadAllBytes(fi2.FullName)));


Names System.Stringপথের নামগুলির জন্য:

public static bool AreFileContentsEqual(String path1, String path2) =>
                   AreFileContentsEqual(new FileInfo(path1), new FileInfo(path2));


অন্যান্য পোস্ট করা উত্তরের মত নয়, এটি যে কোনও ধরণের ফাইলের জন্য চূড়ান্তভাবে সঠিক : বাইনারি, পাঠ্য, মিডিয়া, এক্সিকিউটেবল ইত্যাদি but তবে সম্পূর্ণ বাইনারি তুলনা হিসাবে যে ফাইলগুলি কেবল "গুরুত্বহীন" উপায়ে পৃথক হয় (যেমন বিওএম , লাইন প্রদান , চরিত্রের এনকোডিং , মিডিয়া মেটাডেটা, সাদা স্থান, প্যাডিং, উত্স-কোড মন্তব্য ইত্যাদি) সর্বদা সমান নয়

এই কোডটি উভয় ফাইলকে সম্পূর্ণ মেমরিতে লোড করে, তাই এটি সত্যিকারের বিশাল আকারের ফাইলগুলির সাথে তুলনা করার জন্য ব্যবহার করা উচিত নয় । এই গুরুত্বপূর্ণ সতর্কতার বাইরে, পুরো নেট লোডিংয়ে। নেট জিসির নকশার ভিত্তিতে কোনও জরিমানা হয় না (কারণ এটি ছোট, স্বল্প-জীবন বরাদ্দকে অত্যন্ত সস্তা রাখার জন্য মৌলিকভাবে অনুকূলিত হয় ), এবং প্রকৃতপক্ষে এমনকি ফাইলের আকারগুলি প্রত্যাশিত হওয়ার পরেও অনুকূল হতে পারে থেকে কম হিসাবে 85K কারণ ব্যবহারকারী কোডের একটি সর্বনিম্ন ব্যবহার (যেমন এখানে দেখানো হয়েছে) সর্বাধিক ফাইল কর্মক্ষমতা বিষয় প্রতিনিধিরূপে বোঝা, CLR, BCL, এবং JIT(যেমন) সর্বশেষ নকশা প্রযুক্তি, সিস্টেম কোড, এবং অভিযোজিত রানটাইম অপ্টিমাইজেশন থেকে উপকৃত।

উপরন্তু, এই ধরনের কবিত্বহীন পরিস্থিতিতে জন্য, মাধ্যমে বাইট-বাই-বাইট তুলনা কর্মক্ষমতা সম্পর্কে উদ্বেগ LINQতথ্যসংগ্রহকারী (যেমন এখানে দেখানো হয়েছে) তর্ক করা, ডিস্ক আঘাত থেকে হয় এ সব ফাইলের জন্য ইনপুট / আউটপুট বামন হবে মাত্রার বিভিন্ন আদেশ, সুবিধা দ্বারা বিভিন্ন মেমরি তুলনা বিকল্প। উদাহরণস্বরূপ, যদিও প্রকৃতপক্ষে আমাদের প্রথম অমিলের বিষয়টি পরিত্যাগের "অনুকূলিতকরণ" SequenceEqual দেয় , তবুও এটি ইতিমধ্যে ফাইলগুলির বিষয়বস্তু নিয়ে আসার পরে গুরুত্বপূর্ণ নয়, প্রতিটি ম্যাচ নিশ্চিত করার জন্য সম্পূর্ণ প্রয়োজনীয় ...


3
এটি বড় ফাইলগুলির জন্য ভাল দেখাচ্ছে না। মেমরি ব্যবহারের জন্য ভাল না কারণ এটি বাইট অ্যারের সাথে তুলনা শুরু করার আগে উভয় ফাইলই শেষ পর্যন্ত পড়বে। এজন্য আমি বরং বাফার দিয়ে স্ট্রিমারিডারে যেতে চাই।
Krypto_47

3
@ ক্রিপ্টো_47 আমি এই বিষয়গুলি এবং আমার উত্তরের পাঠ্যে অ্যাপোপ্রেট ব্যবহার সম্পর্কে আলোচনা করেছি।
গ্লেন স্লেডেন

33

রিড কোপসির উত্তর ছাড়াও :

  • দু'টি ফাইল অভিন্ন যেখানে সবচেয়ে খারাপ পরিস্থিতি। এই ক্ষেত্রে বাই বাই বাই ফাইলগুলি তুলনা করা ভাল।

  • যদি দুটি ফাইল অভিন্ন না হয়, আপনি যত তাড়াতাড়ি অভিন্ন নয় তা সনাক্ত করে আপনি কিছুটা দ্রুত গতিতে পারেন।

উদাহরণস্বরূপ, যদি দুটি ফাইল পৃথক দৈর্ঘ্যের হয় তবে আপনি জানেন যে সেগুলি অভিন্ন হতে পারে না এবং তাদের আসল সামগ্রীটির তুলনা করতে হবে না।


10
সম্পূর্ণ হওয়ার জন্য: 1 পজিশনে থাকা বাইটগুলি পৃথক হওয়ার সাথে সাথে অন্যান্য বড় লাভ বন্ধ হয়ে যাচ্ছে।
হেন্ক হলটারম্যান

6
@ হেনক: আমি ভেবেছিলাম এটি খুব সুস্পষ্ট ছিল :-)
ডিটিবি

1
এটি যোগ করার ভাল পয়েন্ট। এটি আমার কাছে সুস্পষ্ট ছিল, সুতরাং আমি এটিকে অন্তর্ভুক্ত করি নি, তবে এটি উল্লেখ করা ভাল।
রিড কোপসি

16

এটি আরও দ্রুত হচ্ছে যদি আপনি ছোট 8 বাইট খণ্ড না পড়েন তবে একটি লুপটি চারপাশে রেখে একটি বৃহত্তর অংশটি পড়ে থাকেন। আমি গড় তুলনার সময়টি 1/4 এ কমিয়েছি।

    public static bool FilesContentsAreEqual(FileInfo fileInfo1, FileInfo fileInfo2)
    {
        bool result;

        if (fileInfo1.Length != fileInfo2.Length)
        {
            result = false;
        }
        else
        {
            using (var file1 = fileInfo1.OpenRead())
            {
                using (var file2 = fileInfo2.OpenRead())
                {
                    result = StreamsContentsAreEqual(file1, file2);
                }
            }
        }

        return result;
    }

    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 = stream1.Read(buffer1, 0, bufferSize);
            int count2 = stream2.Read(buffer2, 0, bufferSize);

            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;
                }
            }
        }
    }
}

13
সাধারণভাবে চেকটি count1 != count2সঠিক নয়। Stream.Read()বিভিন্ন কারণে আপনি যে গণনা সরবরাহ করেছেন তার চেয়ে কম ফিরিয়ে দিতে পারে।
21'8

1
বাফার একটি Int64সমান সংখ্যক ব্লক ধরে রাখবে তা নিশ্চিত করার জন্য , আপনি আকারটি এইভাবে গণনা করতে চাইতে পারেন:const int bufferSize = 1024 * sizeof(Int64)
জ্যাক এ।

14

বাইট-বাই-বাইট তুলনার তুলনায় চেকসাম তুলনাটি সামান্য দ্রুততর হতে পারে কেবলমাত্র এটি হ'ল আপনি একবারে একটি ফাইল পড়ছেন এবং কিছুটা ডিস্ক হেডের জন্য অনুসন্ধানের সময়কে হ্রাস করছেন। এই সামান্য লাভটি হ্যাশ গণনার অতিরিক্ত সময় দ্বারা খুব ভালভাবে খাওয়া যেতে পারে।

এছাড়াও, একটি চেকসাম তুলনা অবশ্যই ফাইলগুলি অভিন্ন হলে দ্রুত হওয়ার কোনও সম্ভাবনা থাকে। যদি সেগুলি না হয় তবে একটি বাই-বাই-বাইট তুলনা প্রথম তফাতটিতে শেষ হবে, এটি আরও দ্রুত তৈরি করবে making

আপনার এটিও বিবেচনা করা উচিত যে একটি হ্যাশ কোড তুলনা কেবল আপনাকে বলে যে এটি সম্ভবত ফাইলগুলি অভিন্ন are 100% নির্দিষ্ট হওয়ার জন্য আপনাকে বাইট বাই বাই তুলনা করতে হবে।

উদাহরণস্বরূপ যদি হ্যাশ কোডটি 32 বিট হয়, আপনি প্রায় 99.99999998% সম্পর্কে নিশ্চিত যে হ্যাশ কোডগুলি মিলে গেলে ফাইলগুলি অভিন্ন। এটি 100% এর কাছাকাছি, তবে আপনার যদি সত্যিই 100% নিশ্চিততার প্রয়োজন হয় তবে তা নয়।


একটি বৃহত্তর হ্যাশ ব্যবহার করুন এবং পরীক্ষা করার সময় আপনি যে ভুলত্রুটি ফেলেছিলেন তার নীচের দিকে আপনি একটি মিথ্যা পজিটিভের প্রতিক্রিয়া পেতে পারেন।
লরেন পেচটেল

আমি হ্যাশ সময় বনাম সময় সন্ধানের বিষয়ে একমত নই। একক মাথা সন্ধানের সময় আপনি প্রচুর গণনা করতে পারেন । যদি সমস্যাগুলি বেশি হয় তবে ফাইলগুলি মেলে আমি প্রচুর বিট সহ একটি হ্যাশ ব্যবহার করব। যদি ম্যাচের যুক্তিসঙ্গত সম্ভাবনা থাকে তবে আমি তাদের একবারে একটি ব্লকের সাথে তুলনা করব, কারণ 1 এমবি ব্লক বলুন। (এমন কোনও ব্লকের আকার চয়ন করুন যাতে সেক্টর কখনই বিভক্ত হয় না তা নিশ্চিত করতে 4k সমানভাবে বিভক্ত হয়))
লরেন পেচটেল

1
@ গুফার চিত্র 99.99999998% বোঝাতে, এটি কম্পিউটিং থেকে আসে, এটি 1 - (1 / (2^32))সম্ভবত কোনও ফাইলের মধ্যে 32-বিট হ্যাশ দেওয়ার সম্ভাবনা। একই হ্যাশযুক্ত দুটি পৃথক ফাইলের সম্ভাবনা একই, কারণ প্রথম ফাইলটি "প্রদত্ত" হ্যাশ মান সরবরাহ করে এবং অন্য ফাইলটি সেই মানের সাথে মেলে কিনা তা আমাদের কেবল বিবেচনা করতে হবে। 64- এবং 128-বিট হ্যাশিংয়ের সম্ভাবনা হ্রাস পেয়ে 99.99999999999999999994% এবং যথাক্রমে 99.9999999999999999999999999999999999997% (যথাক্রমে) হয়ে দাঁড়িয়েছে, যেন এ জাতীয় দুর্গম সংখ্যার সাথে এটি গুরুত্বপূর্ণ।
গ্লেন স্লেডেন

... প্রকৃতপক্ষে, "একই হ্যাশ কোডের সাথে সংঘর্ষিত অসীম অনেকগুলি ফাইল" -র এই সংখ্যাগুলি বেশিরভাগ লোকের পক্ষে ধারণা করা সহজ ধারণার চেয়ে বেশি শক্তিশালী, এই বিষয়টি ব্যাখ্যা করতে পারে যে কেন মানুষ হ্যাশ-হিসাবে গ্রহণ করার ক্ষেত্রে অযৌক্তিকভাবে সন্দেহজনক are সমতা।
গ্লেন স্লেডেন

13

সম্পাদনা করুন: বাইনারি ফাইলগুলির তুলনা করার জন্য এই পদ্ধতিটি কাজ করবে না !

। নেট 4.0 এ, Fileক্লাসে নিম্নলিখিত দুটি নতুন পদ্ধতি রয়েছে:

public static IEnumerable<string> ReadLines(string path)
public static IEnumerable<string> ReadLines(string path, Encoding encoding)

যার অর্থ আপনি ব্যবহার করতে পারেন:

bool same = File.ReadLines(path1).SequenceEqual(File.ReadLines(path2));

1
@ ডিটিবি: এটি বাইনারি ফাইলগুলির জন্য কাজ করে না। আমি বুঝতে পেরে আপনি সম্ভবত ইতিমধ্যে মন্তব্যটি লিখছিলেন এবং আমার পোস্টের শীর্ষে সম্পাদনাটি যুক্ত করেছিলেন। : ও
স্যাম হারওয়েল

@ 280Z28: আমি কিছুই বলিনি ;-)
dtb

আপনারও কি উভয় ফাইল মেমরিতে সঞ্চয় করতে হবে না?
এলোমেলো ইনসানো

নোট করুন যে ফাইলটিতে রিডআলবাইটস ফাংশন রয়েছে যা সিকোয়েন্সএকুয়ালগুলি পাশাপাশি ব্যবহার করতে পারে তাই এটি পরিবর্তে এটি সমস্ত ফাইলগুলিতে কাজ করবে। এবং @ র্যান্ডম ইন্সানো যেমন বলেছিল, এটি মেমরিতে সঞ্চিত হয় তাই ছোট ফাইলগুলির জন্য ব্যবহার করা যথাযথভাবে জরিমানা হয় আমি বড় ফাইলগুলির সাথে এটি ব্যবহারে সতর্কতা অবলম্বন করব।
দায়েদালুস

1
@ ডেডালাসআল্ফা এটি একটি অগণিত ফিরিয়ে দেয়, তাই লাইনগুলি চাহিদা অনুযায়ী লোড করা হবে এবং পুরো সময়ের স্মৃতিতে সংরক্ষণ করা হবে না। অন্যদিকে রিডআলবাইটস অ্যারে হিসাবে পুরো ফাইলটি ফেরত দেয়।
ইলিডানএস 4 মনিকাকে

7

সত্যিই, আমি মনে করি আপনার অনুসন্ধান গাছটিকে যতটা সম্ভব ছাঁটাই করা দরকার।

বাই বাই বাইতে যাওয়ার আগে যাচাই করার বিষয়গুলি:

  1. মাপ কি একই?
  2. বি এ ফাইলের সর্বশেষ বাইট হ'ল ফাইল বি

এছাড়াও, ড্রাইভগুলি ক্রমবর্ধমান বাইটগুলি দ্রুত পড়ার কারণে এক সময় বড় ব্লকগুলি পড়া আরও কার্যকর হবে। বাই-বাই-বাইটে যাওয়ার ফলে কেবলমাত্র আরও অনেক বেশি সিস্টেম কল আসে না, তবে এটি উভয় ফাইল একই ড্রাইভে থাকলে চিরাচরিত হার্ড ড্রাইভের রিড হেডকে প্রায়শই পিছনে পিছনে সন্ধান করে।

বুনা বাফারে খণ্ড এ এবং শঙ্ক বি পড়ুন এবং তাদের তুলনা করুন (অ্যারে ব্যবহার করবেন না quএক্কালগুলি, মন্তব্য দেখুন)। আপনি যা মনে করেন তা আঘাত না করা অবধি ব্লকের আকার টিউন করুন স্মৃতি এবং পারফরম্যান্সের মধ্যে একটি ভাল বাণিজ্য। আপনি তুলনাটি বহু-থ্রেডও করতে পারেন, তবে ডিস্কটি মাল্টি-থ্রেড পড়বেন না।


অ্যারে.একুয়ালগুলি ব্যবহার করা একটি খারাপ ধারণা কারণ এটি সম্পূর্ণ অ্যারের সাথে তুলনা করে। এটি সম্ভবত, কমপক্ষে একটি ব্লক পঠন পুরো অ্যারে পূরণ করবে না।
ডগ ক্লাটার

পুরো অ্যারের তুলনা করা কেন একটি খারাপ ধারণা? কেন একটি ব্লক রিড পূরণ করবে না? অবশ্যই একটি ভাল টিউনিং পয়েন্ট আছে, তবে সে কারণেই আপনি মাপগুলি খেলেন। পৃথক থ্রেডে তুলনা করার জন্য অতিরিক্ত পয়েন্ট।
র্যান্ডমআইসানসো

আপনি যখন বাইট অ্যারের সংজ্ঞা দেন, তখন এর নির্দিষ্ট দৈর্ঘ্য হবে length (উদাঃ - var বাফার = নতুন বাইট [4096]) আপনি যখন ফাইল থেকে একটি ব্লক পড়েন তখন এটি পুরো 4096 বাইটগুলি ফেরত দিতে বা না পারে। উদাহরণস্বরূপ, যদি ফাইলটি 3000 বাইট দীর্ঘ হয়।
ডগ গন্ডগোল

আহ, এখন বুঝলাম! সুসংবাদটি হ'ল পঠন হ'ল অ্যারেতে লোড হওয়া বাইটের সংখ্যাটি ফিরিয়ে দেবে, সুতরাং অ্যারেটি পূরণ করা না গেলে ডেটা থাকবে। যেহেতু আমরা সমতার জন্য পরীক্ষা করছি, পুরানো বাফার ডেটা কোনও ব্যাপার নয়। দস্তাবেজ: msdn.microsoft.com/en-us/library/9kstw824(v=vs.110).aspx
RandomInsano

এছাড়াও গুরুত্বপূর্ণ, সমান () পদ্ধতিটি ব্যবহার করার জন্য আমার সুপারিশটি একটি খারাপ ধারণা। মনোগুলিতে এগুলি মেমরি তুলনা করে যেহেতু উপাদানগুলি মেমরির সাথে সুসংগত। মাইক্রোসফ্ট অবশ্য এটিকে ওভাররাইড করে না, পরিবর্তে কেবলমাত্র একটি রেফারেন্স তুলনা করে যা এখানে সর্বদা মিথ্যা হবে।
র্যান্ডমআইসানসো

4

আমার উত্তরটি @ আলারগুলির একটি ডেরাইভেটিভ তবে কলটিতে বাগটি ঠিক করেছে Stream.Read। অন্যান্য জবাবগুলি এবং ইনপুট বৈধতা যাচাই করে আমি কিছু দ্রুত পথও যুক্ত করছি। সংক্ষেপে বলতে গেলে, এই হওয়া উচিত উত্তর:

using System;
using System.IO;

namespace ConsoleApp4
{
    class Program
    {
        static void Main(string[] args)
        {
            var fi1 = new FileInfo(args[0]);
            var fi2 = new FileInfo(args[1]);
            Console.WriteLine(FilesContentsAreEqual(fi1, fi2));
        }

        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;
                    }
                }
            }
        }
    }
}

বা আপনি যদি দুর্দান্ত-দুর্দান্ত হতে চান তবে আপনি async বৈকল্পিকটি ব্যবহার করতে পারেন:

using System;
using System.IO;
using System.Threading.Tasks;

namespace ConsoleApp4
{
    class Program
    {
        static void Main(string[] args)
        {
            var fi1 = new FileInfo(args[0]);
            var fi2 = new FileInfo(args[1]);
            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;
                    }
                }
            }
        }
    }
}

(var i = 0; i <গণনা; i + = আকারের (দীর্ঘ)) জন্য বিট কনভার্টর বিট আরও ভাল হতে পারে না {যদি (বিটকনভার্টার.ToInt64 (বাফার 1, i)! = বিটকনভার্টার.টুইন্ট 64 (বাফার 2, আই)) false মিথ্যা প্রত্যাবর্তন; ।} `` `
সাইমন

2

আমার পরীক্ষাগুলি দেখায় যে এটি অবশ্যই স্ট্রিম.রেডবাইট () কয়েকবার কল করতে সহায়তা করে তবে বিট কনভার্টারকে প্যাকেজ বাইটে ব্যবহার করা বাইট অ্যারেতে বাইটের তুলনা করার তুলনায় খুব বেশি পার্থক্য রাখে না।

সুতরাং উপরের মন্তব্যে সেই "ম্যাথ.সিলিং এবং পুনরাবৃত্তি" লুপটি সহজতমটির সাথে প্রতিস্থাপন করা সম্ভব:

            for (int i = 0; i < count1; i++)
            {
                if (buffer1[i] != buffer2[i])
                    return false;
            }

আমি অনুমান করি যে এটি তুলনামূলকভাবে আগে বিটকনভার্টার. টোইন্ট 64 কে কিছুটা কাজ করা উচিত (আর্গুমেন্টগুলি পরীক্ষা করুন এবং তারপরে বিট শিফটিং করা) এবং এটি শেষ হবে সমান পরিমাণ কাজ যেমন দুটি অ্যারেতে 8 বাইট তুলনা করা যায় ।


1
অ্যারে.এক্যুয়ালগুলি সিস্টেমে আরও গভীর হয়, সুতরাং এটি সি # তে বাইট বাই করার চেয়ে অনেক দ্রুত হবে। আমি মাইক্রোসফ্টের পক্ষে কথা বলতে পারি না, তবে গভীরভাবে মনো মনোভাবগুলি অ্যারের সাম্যতার জন্য সি এর মেমকিপি () কমান্ড ব্যবহার করে। এর চেয়ে বেশি দ্রুত পেতে পারি না।
এলোমেলো ইনসানো

2
@ র্যান্ডমইনসানো অনুমান করছেন যে আপনি বোঝাচ্ছেন মেমক্যাম্প (), মেমকিপি নয়) ()
এসকিউএল পুলিশ

1

ফাইলগুলি খুব বড় না হলে আপনি ব্যবহার করতে পারেন:

public static byte[] ComputeFileHash(string fileName)
{
    using (var stream = File.OpenRead(fileName))
        return System.Security.Cryptography.MD5.Create().ComputeHash(stream);
}

হ্যাশগুলি সংরক্ষণের জন্য দরকারী হলে হ্যাশগুলির তুলনা করা কেবলমাত্র কার্যকর হবে।

(কোডটি অনেক বেশি পরিষ্কারের সাথে সম্পাদনা করা)


1

অভিন্ন দৈর্ঘ্য সহ বড় ফাইলগুলিতে আর একটি উন্নতি হতে পারে, ফাইলগুলি যথাক্রমে না পড়া, বরং কম বেশি বা কম এলোমেলো ব্লকের তুলনা করা।

আপনি ফাইলের বিভিন্ন অবস্থান থেকে শুরু করে সামনে বা পিছনের দিকের তুলনা করে একাধিক থ্রেড ব্যবহার করতে পারেন।

এইভাবে আপনি ফাইলের মাঝের / শেষের দিকে পরিবর্তনগুলি সনাক্ত করতে পারবেন, ক্রমযুক্ত ক্রিয়াকলাপটি ব্যবহার করে আপনি সেখানে পৌঁছানোর চেয়ে দ্রুত।


1
ডিস্ক ছিটানো এখানে সমস্যার কারণ হতে পারে?
র্যান্ডমআইনসানো

শারীরিক ডিস্ক ড্রাইভ হ্যাঁ, এসএসডি এর এটি পরিচালনা করবে।
দ্য লিজেন্ডারিকপি কোডার

1

আপনার যদি কেবল দুটি ফাইলের তুলনা করার প্রয়োজন হয় তবে আমার ধারণা দ্রুততম উপায়টি হবে (সিতে, আমি জানি না এটি .NET- এর সাথে প্রযোজ্য কিনা)

  1. উভয় ফাইল এফ 1, এফ 2 খুলুন
  2. সম্পর্কিত ফাইলের দৈর্ঘ্য l1, l2 পান
  3. যদি l1! = l2 ফাইলগুলি পৃথক; স্টপ
  4. এমএমএপ () উভয় ফাইল
  5. এমএমএপ () এডি ফাইলগুলিতে মেমক্যাম্প () ব্যবহার করুন

OTOH, আপনার যদি এন ফাইলগুলির একটি সেটে সদৃশ ফাইল রয়েছে কিনা তা খুঁজে পাওয়া দরকার, তবে নিঃসন্দেহে দ্রুততম উপায়টি এন-ওয়ে বিট-বিট তুলনা এড়াতে হ্যাশ ব্যবহার করে নিঃসন্দেহে।


1

কিছু (আশাবাদী) যুক্তিসঙ্গত দক্ষ:

public class FileCompare
{
    public static bool FilesEqual(string fileName1, string fileName2)
    {
        return FilesEqual(new FileInfo(fileName1), new FileInfo(fileName2));
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="file1"></param>
    /// <param name="file2"></param>
    /// <param name="bufferSize">8kb seemed like a good default</param>
    /// <returns></returns>
    public static bool FilesEqual(FileInfo file1, FileInfo file2, int bufferSize = 8192)
    {
        if (!file1.Exists || !file2.Exists || file1.Length != file2.Length) return false;

        var buffer1 = new byte[bufferSize];
        var buffer2 = new byte[bufferSize];

        using (var stream1 = file1.Open(FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            using (var stream2 = file2.Open(FileMode.Open, FileAccess.Read, FileShare.Read))
            {

                while (true)
                {
                    var bytesRead1 = stream1.Read(buffer1, 0, bufferSize);
                    var bytesRead2 = stream2.Read(buffer2, 0, bufferSize);

                    if (bytesRead1 != bytesRead2) return false;
                    if (bytesRead1 == 0) return true;
                    if (!ArraysEqual(buffer1, buffer2, bytesRead1)) return false;
                }
            }
        }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="array1"></param>
    /// <param name="array2"></param>
    /// <param name="bytesToCompare"> 0 means compare entire arrays</param>
    /// <returns></returns>
    public static bool ArraysEqual(byte[] array1, byte[] array2, int bytesToCompare = 0)
    {
        if (array1.Length != array2.Length) return false;

        var length = (bytesToCompare == 0) ? array1.Length : bytesToCompare;
        var tailIdx = length - length % sizeof(Int64);

        //check in 8 byte chunks
        for (var i = 0; i < tailIdx; i += sizeof(Int64))
        {
            if (BitConverter.ToInt64(array1, i) != BitConverter.ToInt64(array2, i)) return false;
        }

        //check the remainder of the array, always shorter than 8 bytes
        for (var i = tailIdx; i < length; i++)
        {
            if (array1[i] != array2[i]) return false;
        }

        return true;
    }
}

1

এখানে কয়েকটি ইউটিলিটি ফাংশন রয়েছে যা আপনাকে দুটি ফাইল (বা দুটি স্ট্রিম) তে অভিন্ন ডেটা রয়েছে কিনা তা নির্ধারণ করতে দেয়।

আমি একটি "দ্রুত" সংস্করণ সরবরাহ করেছি যা বহু-থ্রেডযুক্ত, যেমন এটি টাস্কগুলি ব্যবহার করে বিভিন্ন থ্রেডে বাইট অ্যারে (প্রতিটি ফাইলের মধ্যে যা কিছু ভরা থাকে তা পূরণ করা হয়) তুলনা করে।

যেমনটি প্রত্যাশিত, এটি অনেক দ্রুত (প্রায় 3x দ্রুত) তবে এটি বেশি সিপিইউ গ্রহণ করে (কারণ এটি মাল্টি থ্রেডেড) এবং আরও মেমরি (কারণ এটি তুলনা থ্রেডে দুটি বাইট অ্যারে বাফার প্রয়োজন)।

    public static bool AreFilesIdenticalFast(string path1, string path2)
    {
        return AreFilesIdentical(path1, path2, AreStreamsIdenticalFast);
    }

    public static bool AreFilesIdentical(string path1, string path2)
    {
        return AreFilesIdentical(path1, path2, AreStreamsIdentical);
    }

    public static bool AreFilesIdentical(string path1, string path2, Func<Stream, Stream, bool> areStreamsIdentical)
    {
        if (path1 == null)
            throw new ArgumentNullException(nameof(path1));

        if (path2 == null)
            throw new ArgumentNullException(nameof(path2));

        if (areStreamsIdentical == null)
            throw new ArgumentNullException(nameof(path2));

        if (!File.Exists(path1) || !File.Exists(path2))
            return false;

        using (var thisFile = new FileStream(path1, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
            using (var valueFile = new FileStream(path2, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                if (valueFile.Length != thisFile.Length)
                    return false;

                if (!areStreamsIdentical(thisFile, valueFile))
                    return false;
            }
        }
        return true;
    }

    public static bool AreStreamsIdenticalFast(Stream stream1, Stream stream2)
    {
        if (stream1 == null)
            throw new ArgumentNullException(nameof(stream1));

        if (stream2 == null)
            throw new ArgumentNullException(nameof(stream2));

        const int bufsize = 80000; // 80000 is below LOH (85000)

        var tasks = new List<Task<bool>>();
        do
        {
            // consumes more memory (two buffers for each tasks)
            var buffer1 = new byte[bufsize];
            var buffer2 = new byte[bufsize];

            int read1 = stream1.Read(buffer1, 0, buffer1.Length);
            if (read1 == 0)
            {
                int read3 = stream2.Read(buffer2, 0, 1);
                if (read3 != 0) // not eof
                    return false;

                break;
            }

            // both stream read could return different counts
            int read2 = 0;
            do
            {
                int read3 = stream2.Read(buffer2, read2, read1 - read2);
                if (read3 == 0)
                    return false;

                read2 += read3;
            }
            while (read2 < read1);

            // consumes more cpu
            var task = Task.Run(() =>
            {
                return IsSame(buffer1, buffer2);
            });
            tasks.Add(task);
        }
        while (true);

        Task.WaitAll(tasks.ToArray());
        return !tasks.Any(t => !t.Result);
    }

    public static bool AreStreamsIdentical(Stream stream1, Stream stream2)
    {
        if (stream1 == null)
            throw new ArgumentNullException(nameof(stream1));

        if (stream2 == null)
            throw new ArgumentNullException(nameof(stream2));

        const int bufsize = 80000; // 80000 is below LOH (85000)
        var buffer1 = new byte[bufsize];
        var buffer2 = new byte[bufsize];

        var tasks = new List<Task<bool>>();
        do
        {
            int read1 = stream1.Read(buffer1, 0, buffer1.Length);
            if (read1 == 0)
                return stream2.Read(buffer2, 0, 1) == 0; // check not eof

            // both stream read could return different counts
            int read2 = 0;
            do
            {
                int read3 = stream2.Read(buffer2, read2, read1 - read2);
                if (read3 == 0)
                    return false;

                read2 += read3;
            }
            while (read2 < read1);

            if (!IsSame(buffer1, buffer2))
                return false;
        }
        while (true);
    }

    public static bool IsSame(byte[] bytes1, byte[] bytes2)
    {
        if (bytes1 == null)
            throw new ArgumentNullException(nameof(bytes1));

        if (bytes2 == null)
            throw new ArgumentNullException(nameof(bytes2));

        if (bytes1.Length != bytes2.Length)
            return false;

        for (int i = 0; i < bytes1.Length; i++)
        {
            if (bytes1[i] != bytes2[i])
                return false;
        }
        return true;
    }

0

আমি মনে করি এমন অ্যাপ্লিকেশন রয়েছে যেখানে বাইট বাই বাইকের তুলনায় "হ্যাশ" দ্রুত is আপনার যদি অন্যের সাথে কোনও ফাইলের তুলনা করতে হয় বা কোনও ফটোতে থাম্বনেইল থাকে যা পরিবর্তন করতে পারে। এটি কোথায় এবং কীভাবে ব্যবহার করছে তা নির্ভর করে।

private bool CompareFilesByte(string file1, string file2)
{
    using (var fs1 = new FileStream(file1, FileMode.Open))
    using (var fs2 = new FileStream(file2, FileMode.Open))
    {
        if (fs1.Length != fs2.Length) return false;
        int b1, b2;
        do
        {
            b1 = fs1.ReadByte();
            b2 = fs2.ReadByte();
            if (b1 != b2 || b1 < 0) return false;
        }
        while (b1 >= 0);
    }
    return true;
}

private string HashFile(string file)
{
    using (var fs = new FileStream(file, FileMode.Open))
    using (var reader = new BinaryReader(fs))
    {
        var hash = new SHA512CryptoServiceProvider();
        hash.ComputeHash(reader.ReadBytes((int)file.Length));
        return Convert.ToBase64String(hash.Hash);
    }
}

private bool CompareFilesWithHash(string file1, string file2)
{
    var str1 = HashFile(file1);
    var str2 = HashFile(file2);
    return str1 == str2;
}

এখানে, আপনি দ্রুততম কি তা পেতে পারেন।

var sw = new Stopwatch();
sw.Start();
var compare1 = CompareFilesWithHash(receiveLogPath, logPath);
sw.Stop();
Debug.WriteLine(string.Format("Compare using Hash {0}", sw.ElapsedTicks));
sw.Reset();
sw.Start();
var compare2 = CompareFilesByte(receiveLogPath, logPath);
sw.Stop();
Debug.WriteLine(string.Format("Compare byte-byte {0}", sw.ElapsedTicks));

Allyচ্ছিকভাবে, আমরা একটি ডাটাবেসে হ্যাশ সংরক্ষণ করতে পারি।

আশা করি এটি সাহায্য করতে পারে


0

তবুও অন্য উত্তর, @chsh থেকে প্রাপ্ত। ফাইলের জন্য ইউএসিং এবং শর্টকাট সহ MD5, ফাইলটি বিদ্যমান নেই এবং দৈর্ঘ্যের ভিন্নতা রয়েছে:

/// <summary>
/// Performs an md5 on the content of both files and returns true if
/// they match
/// </summary>
/// <param name="file1">first file</param>
/// <param name="file2">second file</param>
/// <returns>true if the contents of the two files is the same, false otherwise</returns>
public static bool IsSameContent(string file1, string file2)
{
    if (file1 == file2)
        return true;

    FileInfo file1Info = new FileInfo(file1);
    FileInfo file2Info = new FileInfo(file2);

    if (!file1Info.Exists && !file2Info.Exists)
       return true;
    if (!file1Info.Exists && file2Info.Exists)
        return false;
    if (file1Info.Exists && !file2Info.Exists)
        return false;
    if (file1Info.Length != file2Info.Length)
        return false;

    using (FileStream file1Stream = file1Info.OpenRead())
    using (FileStream file2Stream = file2Info.OpenRead())
    { 
        byte[] firstHash = MD5.Create().ComputeHash(file1Stream);
        byte[] secondHash = MD5.Create().ComputeHash(file2Stream);
        for (int i = 0; i < firstHash.Length; i++)
        {
            if (i>=secondHash.Length||firstHash[i] != secondHash[i])
                return false;
        }
        return true;
    }
}

আপনি বলছেন if (i>=secondHash.Length ...কোন পরিস্থিতিতে দুটি এমডি 5 হ্যাশ পৃথক দৈর্ঘ্য হতে পারে?
ব্যাগপাইল্ট

-1

এটি আমি ডেটা না পড়ে প্রথমে দৈর্ঘ্যের তুলনা এবং তারপরে পঠিত বাইট অনুক্রমের সাথে তুলনা করে ভাল কাজ করেছি

private static bool IsFileIdentical(string a, string b)
{            
   if (new FileInfo(a).Length != new FileInfo(b).Length) return false;
   return (File.ReadAllBytes(a).SequenceEqual(File.ReadAllBytes(b)));
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.