সি # তে বড় ফাইলগুলির জন্য চেকসাম তৈরির দ্রুততম উপায় কী?


128

আমাকে কিছু মেশিনে বড় ফাইল সিঙ্ক করতে হবে। ফাইলগুলি আকারে 6 গিগাবাইট পর্যন্ত হতে পারে। সিঙ্কটি কয়েক সপ্তাহে ম্যানুয়ালি করা হবে। আমি ফাইলের নামটি বিবেচনায় নিতে পারি না কারণ তারা যে কোনও সময় পরিবর্তন করতে পারে।

আমার পরিকল্পনাটি হ'ল গন্তব্য পিসিতে এবং সোর্স পিসিতে চেকসাম তৈরি করা এবং তারপরে সমস্ত ফাইল একটি চেকসাম দিয়ে অনুলিপি করা, যা ইতিমধ্যে গন্তব্যে নেই, গন্তব্যে to আমার প্রথম প্রচেষ্টাটি এরকম কিছু ছিল:

using System.IO;
using System.Security.Cryptography;

private static string GetChecksum(string file)
{
    using (FileStream stream = File.OpenRead(file))
    {
        SHA256Managed sha = new SHA256Managed();
        byte[] checksum = sha.ComputeHash(stream);
        return BitConverter.ToString(checksum).Replace("-", String.Empty);
    }
}

সমস্যাটি রানটাইমটি ছিল:
- একটি 1,6 জিবি ফাইলের সাথে SHA256 -> 20 মিনিট
- 1,6 গিগাবাইট ফাইল সহ এমডি 5 সহ -> 6.15 মিনিট

চেকসাম পাওয়ার জন্য আরও ভাল - দ্রুত - উপায় (সম্ভবত আরও ভাল হ্যাশ ফাংশন সহ) থাকতে পারে?


2
আপনার কি সত্যই চেকসাম চেক করা দরকার? আপনি কীভাবে ফাইলগুলি অনুলিপি করছেন? Windows এ আপনার আমি Robocopy এর সর্বশেষ সংস্করণ ... ব্যবহার করেন তাহলে
মেষ

6
হ্যাশিংকে বিরক্ত করার জন্য এখানে দুর্দান্ত টিপস যদি 2 প্রার্থীর ফাইলগুলির মধ্যে ফাইলের আকারগুলি পৃথক হয় stackoverflow.com/a/288756/74585
ম্যাথু লক

উত্তর:


117

এখানে সমস্যাটি হ'ল SHA256Managedএক সময় 4096 বাইট পড়েন ( ফাইল স্ট্রিম থেকে এটি কতটা পড়ে তা দেখতে উত্তরাধিকারসূত্রে FileStreamওভাররাইড করুন Read(byte[], int, int)), যা ডিস্ক আইওয়ের জন্য খুব ছোট বাফার।

গতি জিনিষ আপ মোড়ানো (ভিন্ন ধরনের SHA256 সঙ্গে আমার মেশিন, 1 MD5 জন্য মিনিটে 2 গিগাবাইট ফাইল হ্যাশ 2 মিনিট) FileStreamমধ্যে BufferedStreamএবং সেট যুক্তিসঙ্গতভাবে আকারের বাফারের আকার (আমি ~ 1 MB বাফার সঙ্গে চেষ্টা):

// Not sure if BufferedStream should be wrapped in using block
using(var stream = new BufferedStream(File.OpenRead(filePath), 1200000))
{
    // The rest remains the same
}

3
ঠিক আছে - এটি স্বাতন্ত্র্য তৈরি করেছে - এমডি 5 দিয়ে 1.6 জিবি ফাইলটি হ্যাশ করা আমার বাক্সে 5.2 সেকেন্ড সময় নিয়েছে (কোয়াডকোড @ 2.6 গিগাহার্টজ, 8 জিবি রাম) - দেশীয় বাস্তবায়ন হিসাবে আরও দ্রুত ...
ক্রোনো

4
আমি এটা পাই না আমি এই পরামর্শটি চেষ্টা করেছিলাম তবে পার্থক্যটি কিছুটা হলেও ন্যূনতম। 1024mb ফাইল ডাব্লু / ও বাফারিং 12-14 সেকেন্ড, বাফারিংয়ের সাথে 12-14 সেকেন্ডও - আমি বুঝতে পেরেছি যে শত শত 4 কে ব্লক পড়লে আরও আইও তৈরি হবে তবে আমি নিজেকে জিজ্ঞাসা করব যে ফ্রেমওয়ার্ক বা ফ্রেমওয়ার্কের নীচের নেটিভ এপিআইগুলি ইতিমধ্যে এটি পরিচালনা করে না? ..
খ্রিস্টান ক্যাসট

11
পার্টিতে কিছুটা দেরি হলেও ফাইলস্ট্রিমে স্ট্রিমটিকে বাফারড্রিম্পে জড়ানোর দরকার নেই কারণ আজকাল ফাইল স্ট্রিমেই এটি ইতিমধ্যে হয়ে গেছে। উত্স
রেহেন

আমি কেবল ছোট ফাইলগুলি (<10 এমবি, তবে এমডি 5 পাওয়ার জন্য চিরকাল নিচ্ছি) নিয়ে এই সমস্যাটি নিয়ে যাচ্ছিলাম। যদিও আমি। নেট 4.5 ব্যবহার করি, বাফারড স্ট্রিমের সাহায্যে এই পদ্ধতিটি স্যুইচ করে হ্যাশের সময়টি 8.6 এমবি ফাইলের জন্য প্রায় 8.6 সেকেন্ড থেকে <300 এমএসে কেটে যায়
তাইগস্ট

আমি 1024 কেবি এর পরিবর্তে একটি বাফারডস্ট্রিম / ডাব্লু 512 কেবি ব্যবহার করেছি। 1.8 গিগাবাইট ফাইলটি 30 সেকেন্ডে সমাধান করা হয়েছিল।
হুগো ওয়াসথুইস

61

পুরো ফাইলটি চেকসাম করবেন না, প্রতি 100 মিমি বা আরও বেশি করে চেকসাম তৈরি করবেন না, তাই প্রতিটি ফাইলের চেকসামের সংকলন থাকে।

তারপরে চেকসামের তুলনা করার সময় আপনি প্রথম আলাদা চেকসামের সাথে তুলনা করা, তাড়াতাড়ি বেরিয়ে আসা এবং পুরো ফাইলটি প্রক্রিয়াজাতকরণ থেকে আপনাকে বাঁচাতে পারেন।

এটি অভিন্ন ফাইলগুলির জন্য এখনও পুরো সময় নেয়।


2
আমি ধারণাটি পছন্দ করি তবে এটি আমার দৃশ্যে কাজ করবে না কারণ সময়ের সাথে সাথে আমি অনেকগুলি অপরিবর্তিত ফাইল দিয়ে শেষ করব।
ক্রোনো

1
আপনি কিভাবে ফাইলের প্রতি 100 মিমি চেকসাম করবেন?
স্মিথ

1
সুরক্ষার কারণে চেকসাম ব্যবহার করার সময় একটি ভাল ধারণা নয়, কারণ আক্রমণকারী কেবলমাত্র আপনাকে বাদ দেওয়া বাইটগুলি পরিবর্তন করতে পারে।
বি কেইনার

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

1
@ b.kiener কোনও বাইট বাদ নেই। আপনি তাকে ভুল বুঝেছেন।
সুরেশ ফালাহাটি

47

অ্যান্টন গোগোলেভ যেমন উল্লেখ করেছেন , ফাইল স্ট্রিম ডিফল্টরূপে একবারে 4096 বাইট পড়ে, তবে আপনি ফাইল স্ট্রিম নির্মাণকারী ব্যবহার করে অন্য কোনও মান নির্দিষ্ট করতে পারেন:

new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 16 * 1024 * 1024)

নোট করুন যে মাইক্রোসফ্ট থেকে ব্র্যাড আব্রামস 2004 সালে লিখেছেন:

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

উৎস


22

Md5sum.exe এর উইন্ডো পোর্টটি চালান । এটি নেট অ্যাপ্লিকেশন হিসাবে প্রায় দ্বিগুণ দ্রুত (কমপক্ষে আমার মেশিনে একটি 1.2 গিগাবাইট ফাইল ব্যবহার করে)

public static string Md5SumByProcess(string file) {
    var p = new Process ();
    p.StartInfo.FileName = "md5sum.exe";
    p.StartInfo.Arguments = file;            
    p.StartInfo.UseShellExecute = false;
    p.StartInfo.RedirectStandardOutput = true;
    p.Start();
    p.WaitForExit();           
    string output = p.StandardOutput.ReadToEnd();
    return output.Split(' ')[0].Substring(1).ToUpper ();
}

3
WOW - pc-tools.net/win32/md5sums থেকে md5sums.exe ব্যবহার করা এটি সত্যই দ্রুত করে তোলে। 1681457152 বাইটস, 8672 এমএস = 184.91 এমবি / সেকেন্ড -> 1,6 জিবি ~ 9 সেকেন্ড এটি আমার উদ্দেশ্যটির জন্য দ্রুত যথেষ্ট হবে।
ক্রোনো

16

ঠিক আছে - আপনাদের সকলকে ধন্যবাদ - আমাকে এটিকে গুটিয়ে রাখুন:

  1. একটি "নেটিভ" এক্সটি ব্যবহার করে হ্যাশিং করতে 6 মিনিট থেকে 10 সেকেন্ড সময় লেগেছিল যা বিশাল।
  2. বাফার বাড়ানো আরও দ্রুত ছিল - 1.6 জিবি ফাইলটি নেট থেকে এমডি 5 ব্যবহার করে 5.2 সেকেন্ড সময় নিয়েছে, তাই আমি এই সমাধানটি দিয়ে যাব - আবার ধন্যবাদ

10

আমি এই কোডটি চালিয়ে বাফার আকার দিয়ে পরীক্ষা করেছি

using (var stream = new BufferedStream(File.OpenRead(file), bufferSize))
{
    SHA256Managed sha = new SHA256Managed();
    byte[] checksum = sha.ComputeHash(stream);
    return BitConverter.ToString(checksum).Replace("-", String.Empty).ToLower();
}

এবং আমি 29½ জিবি আকারের একটি ফাইল দিয়ে পরীক্ষা করেছি, ফলাফল ছিল were

  • 10.000: 369,24 এস
  • 100.000: 362,55s
  • 1.000.000: 361,53 এস
  • 10.000.000: 434,15 এস
  • 100.000.000: 435,15 এস
  • 1.000.000.000: 434,31 এস
  • এবং 376,22 গুলি মূল ব্যবহার করার সময়, কোনওটিই বাফার কোড নয়।

আমি একটি আই 5 2500 কে সিপিইউ, 12 জিবি র‌্যাম এবং একটি ওসিজেড ভার্টেক্স 4 256 জিবি এসএসডি ড্রাইভ চালাচ্ছি।

তাই আমি ভেবেছিলাম, স্ট্যান্ডার্ড 2TB হার্ডড্রাইভ সম্পর্কে কী। এবং ফলাফল এই মত ছিল

  • 10.000: 368,52 এস
  • 100.000: 364,15 এস
  • 1.000.000: 363,06 এস
  • 10.000.000: 678,96 এস
  • 100.000.000: 617,89s
  • 1.000.000.000: 626,86 গুলি
  • এবং কারও জন্য 368,24 বাফার করেনি

সুতরাং আমি কোনও বাফার বা সর্বোচ্চ 1 মিলের বাফারকে সুপারিশ করব।


আমি এটা পেতে না। এই পরীক্ষাটি কীভাবে অ্যান্টন গোগোলেভের গৃহীত উত্তরের বিরোধিতা করতে পারে?
বন্ধুবাবল

আপনি কি আপনার ডেটাতে প্রতিটি ক্ষেত্রের বর্ণনা যুক্ত করতে পারেন?
ভিডিওগুয়ে

2

আপনি কিছু ভুল করছেন (সম্ভবত খুব ছোট পড়া বাফার)। অসম্পূর্ণ বয়সের এমন একটি মেশিনে (২০০২ থেকে অ্যাথলন ২x1800 এমপি) যেটির ডিস্কে ডিএমএ রয়েছে সম্ভবত অসম্পূর্ণতার বাইরে (sequ..6 এম / সিক্যুয়ালটি পড়ার সময় ধীর গতিতে):

"এলোমেলো" ডেটা সহ একটি 1 জি ফাইল তৈরি করুন:

# dd if=/dev/sdb of=temp.dat bs=1M count=1024    
1073741824 bytes (1.1 GB) copied, 161.698 s, 6.6 MB/s

# time sha1sum -b temp.dat
abb88a0081f5db999d0701de2117d2cb21d192a2 *temp.dat

1m5.299s

# time md5sum -b temp.dat
9995e1c1a704f9c1eb6ca11e7ecb7276 *temp.dat

1m58.832s

এটিও অদ্ভুত, এমডি 5 আমার জন্য sha1 এর তুলনায় ধারাবাহিকভাবে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে।


হ্যাঁ - আমি বাফার বাড়াতে চেষ্টা করব - যেমন অ্যান্টন গোগোলেভ সুজেস্টেড। আমি এটি একটি "নেটিভ" MD5.exe দিয়ে চালিয়েছি যা 1,6 জিবি ফাইলের সাথে 9 সেকেন্ড সময় নিয়েছিল।
ক্রোনো

2

আমি জানি যে আমি পার্টি করতে দেরি করেছিলাম তবে সমাধানটি বাস্তবায়নের আগে পরীক্ষা করেছিলাম।

আমি MD5 বর্গ Inbuilt এবং বিরুদ্ধে পরীক্ষা সম্পাদন করেছেন md5sum.exe । আমার ক্ষেত্রে ইনবিল্ট ক্লাসটি 13 সেকেন্ড নিয়েছিল যেখানে এমডি 5সাম.একটি প্রতি রানে প্রায় 16-18 সেকেন্ডের কাছাকাছি যায়।

    DateTime current = DateTime.Now;
    string file = @"C:\text.iso";//It's 2.5 Gb file
    string output;
    using (var md5 = MD5.Create())
    {
        using (var stream = File.OpenRead(file))
        {
            byte[] checksum = md5.ComputeHash(stream);
            output = BitConverter.ToString(checksum).Replace("-", String.Empty).ToLower();
            Console.WriteLine("Total seconds : " + (DateTime.Now - current).TotalSeconds.ToString() + " " + output);
        }
    }

2

আপনি এক্সএক্সএইচ.এস নেট দেখতে পারেন ( https://github.com/wilhelmliao/xxHash.NET )
এক্সএক্সএইচ অ্যালগরিদম অন্য সমস্তগুলির চেয়ে দ্রুত বলে মনে হচ্ছে।
এক্সএক্সএল সাইটে কয়েকটি মানদণ্ড: https://github.com/Cyan4973/xxHash

পিএস: আমি এখনও এটি ব্যবহার করি নি।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.