一直在玩 WOW ,发现网上的 MD5 计算工具都没有自动比较功能,每次下载更新计算后,都要自己一个一个字母核对,比较麻烦。
最近开始学习 C# ,用 .NET ,做了一个简单的文件MD5码自动计算比较器。
主要对 多线程更新 winform 不是特别清楚,绕来绕去,搞得很晕乎,主要代码如下, 还请各位大侠多多指点,谢谢!
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using System.Security.Cryptography; 10 using System.IO; 11 using System.Threading; 12 13 namespace FileMD5 { 14 public partial class MainForm : Form { 15 public MainForm() { 16 InitializeComponent(); 17 } 18 19 private void button_file_Click(object sender, EventArgs e) { 20 OpenFileDialog fileDialog = new OpenFileDialog(); 21 fileDialog.Title = "请选择文件"; 22 fileDialog.RestoreDirectory = true; 23 24 if (fileDialog.ShowDialog() == DialogResult.OK) { 25 textBox_file.Text = fileDialog.FileName; 26 textBox_result.Text = ""; 27 FileInfo file = new FileInfo(fileDialog.FileName); 28 fileSzie = file.Length; 29 showFilesize(fileSzie); 30 } 31 32 } 33 34 private void button_exit_Click(object sender, EventArgs e) { 35 this.Close(); 36 this.Dispose(); 37 } 38 39 private void button_check_Click(object sender, EventArgs e) { 40 checkResult(); 41 } 42 43 MD5 md5 = (MD5)CryptoConfig.CreateFromName("MD5"); 44 long fileSzie = 0; 45 46 private void button_calc_Click(object sender, EventArgs e) { 47 string file = textBox_file.Text; 48 49 if (file.Length == 0) { 50 textBox_result.Text = "请先重新选择文件!"; 51 return; 52 } 53 54 FileStream fs = null; 55 try { 56 fs = new FileStream(file, FileMode.Open, FileAccess.Read); 57 } catch (SystemException) { 58 textBox_result.Text = "文件打开错误,请重新选择文件!"; 59 return; 60 } 61 62 //对于大于 100M 的文件启用多线程 63 if (fs.Length > 100L * 1024 * 1024) { 64 65 string message = "文件已经超过 100M ,需要较长的计算时间。\n软件将启动后台线程进行处理。是否继续?"; 66 string caption = "文件较大"; 67 MessageBoxButtons buttons = MessageBoxButtons.YesNo; 68 69 if (MessageBox.Show(message, caption, buttons) == System.Windows.Forms.DialogResult.No) { 70 fs.Close(); 71 textBox_result.Text = "文件较大,未计算。"; 72 return; 73 } 74 textBox_result.Text = "正在计算中,请稍候......"; 75 button_calc.Enabled = false; 76 button_file.Enabled = false; 77 78 Thread thread = new Thread(new ParameterizedThreadStart(calcMD5)); 79 thread.Start(fs); 80 81 } else { 82 calcMD5(fs); 83 } 84 } 85 86 //建立一个 object 参数的函数,是为了处理线程调用中,使用参数的问题。 87 private void calcMD5(object fs) { 88 calcMD5((FileStream)fs); 89 } 90 91 // Invoke 函数需要使用的委托 92 delegate void updateWindows(byte[] result); 93 94 private void calcMD5(FileStream fs) { 95 byte[] md5byte = md5.ComputeHash(fs); 96 97 if (this.InvokeRequired) { 98 this.Invoke(new updateWindows(showResult), md5byte); 99 } else { 100 showResult(md5byte); 101 } 102 fs.Close(); 103 } 104 105 private void showResult(byte[] md5byte) { 106 int i, j; 107 StringBuilder sb = new StringBuilder(32); 108 foreach (byte b in md5byte) { 109 i = Convert.ToInt32(b); 110 j = i >> 4; 111 sb.Append(Convert.ToString(j, 16)); 112 j = ((i << 4) & 0x00ff) >> 4; 113 sb.Append(Convert.ToString(j, 16)); 114 } 115 116 String result = sb.ToString().ToUpper(); 117 118 textBox_result.Text = result; 119 button_calc.Enabled = true; 120 button_file.Enabled = true; 121 checkResult(); 122 123 } 124 125 private void checkResult() { 126 127 string result = textBox_result.Text; 128 129 if (textBox_md5.Text.Length == 0) { 130 textBox_compare.Text = ""; 131 textBox_compare.Visible = false; 132 return; 133 } 134 135 if(result.Length != 32 ) { 136 textBox_compare.Visible = true; 137 textBox_compare.BackColor = Color.Pink; 138 textBox_compare.Text = "计算结果框中不是MD5码,请先进行计算!"; 139 return; 140 } 141 142 if (textBox_md5.Text.Trim().ToUpper().Equals(result.ToUpper())) { 143 textBox_compare.Visible = true; 144 textBox_compare.BackColor = Color.LightGreen; 145 textBox_compare.Text = "MD5码 已匹配,文件未被修改,可放心使用!"; 146 } else { 147 textBox_compare.Visible = true; 148 textBox_compare.BackColor = Color.Red; 149 textBox_compare.Text = "MD5码 不匹配,文件已被修改,请小心!"; 150 } 151 } 152 153 private void showFilesize(long size) { 154 155 float d_size; 156 string unit = "Byte"; 157 158 if (size > 1024 * 1024 * 1024) { //大于 1G 的显示 159 d_size = size / (float)(1024 * 1024 * 1024); 160 unit = "GB"; 161 } else { 162 if (size > 1024 * 1024) { //大于 1M 的显示 163 d_size = size / (float)(1024 * 1024); 164 unit = "MB"; 165 } else { 166 if (size > 1024) { //大于 1K 的显示 167 d_size = size / (float)(1024); 168 unit = "KB"; 169 } else { 170 d_size = size; 171 } 172 } 173 } 174 textBox_filesize.Text = string.Format(" {0:F} {1} ( {2:N0}字节 )", d_size, unit, size); 175 } 176 } 177 }
完整的 VS2010 项目见:
http://files.cnblogs.com/jacs/FileMD5.rar
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>