客户端开发小结
因为项目需要,改web端项目到客户端,就开始了第一次客户端开发。
采用c#语言开发,其实还是蛮简单的,直接拉控件摆放到面板上,需要发生点击事件就点两下,出来一个双击函数,在函数里写要操作的方法就好了。
这次主要遇到的难点有两方面吧:1、c#调用外部可执行程序gawk;2、awk的使用
1、c#调用外部可执行程序
这里为什么要调用gawk咧?主要是考虑到,程序的主要用途是进行文本的处理,而对于文本的处理awk(gawk是awk的windows版本)处理起来相当简单。
怎么调用gawk咧?
1: Process p = new Process();
2: p.StartInfo.FileName = "cmd.exe";
3: p.StartInfo.UseShellExecute = false;
4: p.StartInfo.RedirectStandardInput = true;
5: p.StartInfo.RedirectStandardOutput = true;
6: p.StartInfo.RedirectStandardError = true;
7: p.StartInfo.CreateNoWindow = true;
8: p.Start();
9: p.StandardInput.WriteLine("cd " + newLocation);
10: //按照qq号进行过滤
11: p.StandardInput.WriteLine("gawk ..../*此处省略*/);
12: p.StandardInput.WriteLine("exit");
13: string strRst = p.StandardOutput.ReadToEnd();
14: p.Close();
这里犯了一个错误就是我最开始以为可以直接调用gawk.exe执行文件,但是发现完全行不通,最后还是采用这种本办法,先调用cmd.exe,再进入gawk的目录,调用gawk.exe,执行gawk的命令。
这里的
1: p.StandardInput.WriteLine("gawk ..../*此处省略*/);
可以不断的write新的语句进去,感觉应该是同步执行的。但是这里如果出现c#代码,就会异步执行,注意。
2、awk的使用总结
awk的使用总结分为一下几点:文件操作、多文件操作
文件操作:
awk 双引号+大括号+执行语句+反大括号+反双引号;(在windows下需用双引号,linux下用单引号)。
1: gawk "{if(!(++a[substr($1,0,1)]>1)){print $0 >> \"temp2013-04-22-04-14-48.txt\"}else{print $0 >> \".\\sadQQData\\sadQQData2013-04-22-04-14-48.txt\"}}" C:\\Users\\share\\Desktop\\数据包过滤系统\\test.txt
对于去重的方法,网上有很多啦,比如:
1: gawk "!(a[$1]++)" 22.txt 去掉重复的数据条,会保留一条
2: gawk "!(++a[$1]>6)" 22.txt 处理能包涵超过6个重复数据的文本,会保留6条
但是对于要去掉所有重复的数据,即只要重复了,一条也不保留的情况。就有点够呛了。我的处理方式是:
首先按照去重的方式过滤一遍,把干净数据包和脏数据包放到两个文件中,这时候脏数据包里的所有数据都表示在源数据包中重复出现超过次数的数据,干净数据包里的数据有正常数据和出现超过次数的数据的几条(看去重的时候阈值)。这个时候再用两个文件比较,把在臧数据包中出现过的数据从干净数据包中去掉。这个时候就是完全干净的数据包了。
多文件处理:
这个一定要看下NR(Number of Record)、FNR(File Number of Record)、NF(NUmber of Field)。
通过对NR=FNR,表示读取第一个文件,NR>FNR,表示读取第二个文件内容。
了解了这几个东东对于多文件操作就很简单啦。看查看:http://www.letuknowit.com/topics/20120329/sample-about-awk-build-in-variable-nr-fnr-nf.html
附上客户端软件打包源码:
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.IO;
10: using System.Collections;
11: using System.Runtime.InteropServices;
12: using System.Threading;
13: using System.Diagnostics;
14: namespace FileWatch
15: {
16: public partial class Form1 : Form
17: {
18: // File System Watcher object.
19: private FileSystemWatcher watcher;
20: private delegate void UpdateWatchTextDelegate(string newText);
21:
22: public Form1()
23: {
24: InitializeComponent();
25:
26: this.watcher = new FileSystemWatcher();
27: this.watcher.Deleted +=
28: new FileSystemEventHandler(this.OnDelete);
29: this.watcher.Renamed +=
30: new RenamedEventHandler(this.OnRenamed);
31: this.watcher.Changed +=
32: new FileSystemEventHandler(this.OnChanged);
33: this.watcher.Created +=
34: new FileSystemEventHandler(this.OnCreate);
35:
36: DirectoryInfo aDir = new DirectoryInfo(@"C:\FileLogs");
37: if (!aDir.Exists)
38: aDir.Create();
39: }
40:
41: // Utility method to update watch text.
42: public void UpdateWatchText(string newText)
43: {
44: //lblWatch.Text = newText;
45: }
46:
47: // Define the event handlers.
48: public void OnChanged(object source, FileSystemEventArgs e)
49: {
50: try
51: {
52: lblWatch.Text = "123";
53: StreamWriter sw =
54: new StreamWriter("C:/FileLogs/Log.txt", true);
55: sw.WriteLine("File: {0} {1}", e.FullPath,
56: e.ChangeType.ToString());
57: sw.Close();
58: this.BeginInvoke(new UpdateWatchTextDelegate(UpdateWatchText),
59: "Wrote change event to log");
60: }
61: catch (IOException)
62: {
63: this.BeginInvoke(new UpdateWatchTextDelegate(UpdateWatchText),
64: "Error Writing to log");
65: }
66: }
67:
68: public void OnRenamed(object source, RenamedEventArgs e)
69: {
70: try
71: {
72: StreamWriter sw =
73: new StreamWriter("C:/FileLogs/Log.txt", true);
74: sw.WriteLine("File renamed from {0} to {1}", e.OldName,
75: e.FullPath);
76: sw.Close();
77: this.BeginInvoke(new UpdateWatchTextDelegate(UpdateWatchText),
78: "Wrote renamed event to log");
79: }
80: catch (IOException)
81: {
82: this.BeginInvoke(new UpdateWatchTextDelegate(UpdateWatchText),
83: "Error Writing to log");
84: }
85: }
86:
87: public void OnDelete(object source, FileSystemEventArgs e)
88: {
89: try
90: {
91: StreamWriter sw =
92: new StreamWriter("C:/FileLogs/Log.txt", true);
93: sw.WriteLine("File: {0} Deleted", e.FullPath);
94: sw.Close();
95: this.BeginInvoke(new UpdateWatchTextDelegate(UpdateWatchText),
96: "Wrote delete event to log");
97: }
98: catch (IOException)
99: {
100: this.BeginInvoke(new UpdateWatchTextDelegate(UpdateWatchText),
101: "Error Writing to log");
102: }
103: }
104:
105: public void OnCreate(object source, FileSystemEventArgs e)
106: {
107: try
108: {
109: StreamWriter sw =
110: new StreamWriter("C:/FileLogs/Log.txt", true);
111: sw.WriteLine("File: {0} Created", e.FullPath);
112: sw.Close();
113: this.BeginInvoke(new UpdateWatchTextDelegate(UpdateWatchText),
114: "Wrote create event to log");
115: }
116: catch (IOException)
117: {
118: this.BeginInvoke(new UpdateWatchTextDelegate(UpdateWatchText),
119: "Error Writing to log");
120: }
121: }
122:
123: private void cmdBrowse_Click(object sender, EventArgs e)
124: {
125: if (FileDialog.ShowDialog() != DialogResult.Cancel)
126: {
127: txtLocation.Text = FileDialog.FileName;
128: cmdWatch.Enabled = true;
129: }
130: }
131:
132: private void cmdWatch_Click(object sender, EventArgs e)
133: {
134: watcher.Path = Path.GetDirectoryName(txtLocation.Text);
135: watcher.Filter = Path.GetFileName(txtLocation.Text);
136: watcher.NotifyFilter = NotifyFilters.LastWrite |
137: NotifyFilters.FileName | NotifyFilters.Size;
138: //先进行文件格式校验
139: bool result = checkFile();
140: checkNum();
141: int i, qqi, ipi, vki, happyi;
142: List<string> qq = new List<string>();
143: List<string> ip = new List<string>();
144: List<string> vk = new List<string>();
145: if (result == true) {
146: String line;
147: StreamReader fileStream = new StreamReader(txtLocation.Text, Encoding.Default);
148: for (i = 0; (line = fileStream.ReadLine()) != null;i++){}
149: string taskId = DateTime.Now.ToString("yyyy-MM-dd-hh-mm-ss");
150: dataAddr.Text = taskId;
151: string happyPath = @".\\happyData\\happyData" + taskId + ".txt";
152: //dataAddr.Text = happyPath;
153: string sadQQPath = @".\\sadQQData\\sadQQData" + taskId + ".txt";
154: string sadIPPath = @".\\sadIPData\\sadIPData" + taskId + ".txt";
155: string sadVKPath = @".\\sadVKData\\sadVKData" + taskId + ".txt";
156: string suspectPath = @".\\suspectData\\suspectData" + taskId + ".txt";
157: string temp = @"temp" + taskId + ".txt";
158: if (!File.Exists(happyPath))
159: {
160: using (StreamWriter sw = File.CreateText(happyPath))
161: {
162: //sw.WriteLine("Hello");
163: }
164: }
165: if (!File.Exists(sadQQPath))
166: {
167: using (StreamWriter sw = File.CreateText(sadQQPath))
168: {
169: //sw.WriteLine("Hello");
170: }
171: }
172: if (!File.Exists(sadIPPath))
173: {
174: using (StreamWriter sw = File.CreateText(sadIPPath))
175: {
176: //sw.WriteLine("Hello");
177: }
178: }
179: if (!File.Exists(sadVKPath))
180: {
181: using (StreamWriter sw = File.CreateText(sadVKPath))
182: {
183: //sw.WriteLine("Hello");
184: }
185: }
186: string strRst = awk(txtLocation.Text.Replace("\\","\\\\"), happyPath, sadQQPath, sadIPPath, sadVKPath, temp,suspectPath);
187: Console.WriteLine(strRst);
188: Console.ReadLine();
189:
190: //执行完后开始计数
191: StreamReader qqStream = new StreamReader(sadQQPath, Encoding.Default);
192: StreamReader ipStream = new StreamReader(sadIPPath, Encoding.Default);
193: StreamReader vkStream = new StreamReader(sadVKPath, Encoding.Default);
194: StreamReader happyStream = new StreamReader(happyPath, Encoding.Default);
195: for (qqi = 0; (qqStream.ReadLine()) != null; qqi++){}
196: for (ipi = 0; (ipStream.ReadLine()) != null; ipi++){}
197: for (vki = 0; (vkStream.ReadLine()) != null; vki++){}
198: for (happyi = 0; (happyStream.ReadLine()) != null; happyi++) { }
199: //文件总行数
200: totalNum.Text = i.ToString();
201: ipSusNum.Text = ipi.ToString();
202: QQSusNum.Text = qqi.ToString();
203: vkSusNum.Text = vki.ToString();
204: if (ipSusNum.Text == totalNum.Text || QQSusNum.Text == totalNum.Text || vkSusNum.Text == totalNum.Text)
205: {
206: normalNum.Text = "0";
207: }
208: else {
209: normalNum.Text = happyi.ToString();
210: }
211:
212: suspectNum.Text = (i-Int32.Parse(normalNum.Text)).ToString();
213: fileStream.Close();
214: }
215: else if (result == false) {
216:
217: }
218: watcher.EnableRaisingEvents = true;
219: }
220:
221:
222: private bool checkFile() {
223: if (txtLocation.Text!= "")
224: {
225: if(ipNum.Text==""&&vkNum.Text==""&&QQFirstNum.Text==""&&QQNum.Text==""){
226: MessageBox.Show("请填写过滤规则!");
227: return false;
228: }
229: return true;
230: }
231: else {
232: MessageBox.Show("请选择文件!");
233: return false;
234: }
235:
236: }
237: private void checkNum() {
238: if(QQFirstNum.Text == ""){
239: QQFirstNum.Text = "9";
240:
241: }
242: if (QQNum.Text == "") {
243: QQNum.Text = "1";
244:
245: }
246: if (vkNum.Text == "")
247: {
248: vkNum.Text = "10000000";
249:
250: }
251: if (ipNum.Text == "")
252: {
253: ipNum.Text = "10000000";
254:
255: }
256: }
257:
258: private string awk(string path,string happyPath,string sadQQPath,string sadIPPath,string sadVKPath,string temp,string suspectPath)
259: {
260: string location = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
261:
262: string newLocation = location.Replace("\\","\\\\");
263: //MessageBox.Show(newLocation);
264: Process p = new Process();
265: p.StartInfo.FileName = "cmd.exe";
266: p.StartInfo.UseShellExecute = false;
267: p.StartInfo.RedirectStandardInput = true;
268: p.StartInfo.RedirectStandardOutput = true;
269: p.StartInfo.RedirectStandardError = true;
270: p.StartInfo.CreateNoWindow = true;
271: p.Start();
272: p.StandardInput.WriteLine("cd " + newLocation);
273: //按照qq号进行过滤
274: p.StandardInput.WriteLine("gawk \"{if(!(++a[substr($1,0," + Int32.Parse(QQFirstNum.Text) + ")]>" + Int32.Parse(QQNum.Text) + ")){print $0 >> \\\"" + temp + "qq\\\"}else{print $0 >> \\\"" + sadQQPath + "\\\"}}\" "+path+"");
275: //按照ip进行过滤
276: p.StandardInput.WriteLine("gawk \"{if(!(++a[$2]>" + Int32.Parse(ipNum.Text) + ")){print $0 >> \\\"" + temp + "ip\\\"}else{print $0 >> \\\"" + sadIPPath + "\\\"}}\" " + path);
277:
278: //p.StandardInput.WriteLine("gawk \"{if(NR==FNR){a[$2]++}if(NR>FNR){if(a[$2]>=1){print $0 >>\\\""+sadIPPath+"\\\"}else{print $0 >> \\\""+temp+"ip2\\\"}}}\" " + sadIPPath +" "+ temp+"ip");
279: //按照vk进行过滤
280: p.StandardInput.WriteLine("gawk \"{if(!(++a[$3]>" + Int32.Parse(vkNum.Text) + ")){print $0 >> \\\"" + temp + "vk\\\"}else{print $0 >> \\\"" + sadVKPath + "\\\"}}\" " + path);
281: //对qq好完全去重
282: p.StandardInput.WriteLine("gawk \"{if(NR==FNR){a[substr($1,0," + Int32.Parse(QQFirstNum.Text) + ")]++}if(NR>FNR){if(a[substr($1,0," + Int32.Parse(QQFirstNum.Text) + ")]>=1){print $0 >> \\\"" + sadQQPath + "\\\"}else{print $0 >> \\\"" + temp + "qq2\\\"}}}\" " + sadQQPath + " " + temp + "qq");
283:
284: //对重复ip完全去重
285: p.StandardInput.WriteLine("gawk \"{if(NR==FNR){a[$2]++}if(NR>FNR){if(a[$2]>=1){print $0 >> \\\"" + sadIPPath + "\\\"}else{print $0 >> \\\"" + temp + "ip2\\\"}}}\" " + sadIPPath + " " + temp + "ip");
286:
287: //对vk完全去重
288: p.StandardInput.WriteLine("gawk \"{if(NR==FNR){a[$3]++}if(NR>FNR){if(a[$3]>=1){print $0 >> \\\"" + sadVKPath + "\\\"}else{print $0 >> \\\"" + temp + "vk2\\\"}}}\" " + sadVKPath + " " + temp + "vk");
289: //过滤完之后将tempqq、tempip、tempvk进行合并去重得到干净数据包
290: DialogResult dialogResult = MessageBox.Show("数据包运行可能会比较慢,请不要着急~~", "温馨提示", MessageBoxButtons.OK, MessageBoxIcon.Question);
291: if (dialogResult == DialogResult.OK)
292: {
293: //Application.ExitThread();
294:
295: FileInfo tempqq2 = new FileInfo(temp + "qq2");
296: if (tempqq2.Exists)
297: {
298: //MessageBox.Show("qq2");
299: p.StandardInput.WriteLine("gawk \"{print $0 >> \\\"" + temp + "total\\\"}\" " + temp + "qq2");
300: }
301: else
302: {
303: //MessageBox.Show("qq");
304: p.StandardInput.WriteLine("gawk \"{print $0 >> \\\"" + temp + "total\\\"}\" " + temp + "qq");
305: }
306: FileInfo tempip2 = new FileInfo(temp + "ip2");
307: if (tempip2.Exists)
308: {
309: p.StandardInput.WriteLine("gawk \"{print $0 >> \\\"" + temp + "total\\\"}\" " + temp + "ip2");
310: }
311: else
312: {
313: p.StandardInput.WriteLine("gawk \"{print $0 >> \\\"" + temp + "total\\\"}\" " + temp + "ip");
314: }
315: FileInfo tempvk2 = new FileInfo(temp + "vk2");
316: if (tempvk2.Exists)
317: {
318: p.StandardInput.WriteLine("gawk \"{print $0 >> \\\"" + temp + "total\\\"}\" " + temp + "vk2");
319: }
320: else {
321: p.StandardInput.WriteLine("gawk \"{print $0 >> \\\"" + temp + "total\\\"}\" " + temp + "vk");
322: }
323: //p.StandardInput.WriteLine("gawk \"{print $0 >> \\\"" + temp + "total\\\"}\" " + temp + "ip2");
324: //p.StandardInput.WriteLine("gawk \"{print $0 >> \\\"" + temp + "total\\\"}\" " + temp + "vk2");
325: p.StandardInput.WriteLine("gawk \"{if(++a[$0]>=3){print $0 >> \\\"" + happyPath + "\\\"}}\" " + temp + "total");
326: }
327: p.StandardInput.WriteLine("exit");
328: string strRst = p.StandardOutput.ReadToEnd();
329: p.Close();
330: //删除临时文件
331: FileInfo tempqq = new FileInfo(temp+"qq");
332: if (tempqq.Exists)
333: {
334: tempqq.Delete();
335: }
336: FileInfo tempip = new FileInfo(temp + "ip");
337: if (tempip.Exists)
338: {
339: tempip.Delete();
340: }
341: FileInfo tempvk = new FileInfo(temp + "vk");
342: if (tempvk.Exists)
343: {
344: tempvk.Delete();
345: }
346: FileInfo tempqq3 = new FileInfo(temp + "qq2");
347: if (tempqq3.Exists)
348: {
349: tempqq3.Delete();
350: }
351: FileInfo tempip3 = new FileInfo(temp + "ip2");
352: if (tempip3.Exists)
353: {
354: tempip3.Delete();
355: }
356: FileInfo tempvk3 = new FileInfo(temp + "vk2");
357: if (tempvk3.Exists)
358: {
359: tempvk3.Delete();
360: }
361: FileInfo temptotal = new FileInfo(temp + "total");
362: if (temptotal.Exists)
363: {
364: temptotal.Delete();
365: }
366: return strRst;
367: }
368: private void txtLocation_TextChanged(object sender, EventArgs e)
369: {
370:
371: }
372:
373: private void Form1_Load(object sender, EventArgs e)
374: {
375:
376: }
377:
378: private void FileDialog_FileOk(object sender, CancelEventArgs e)
379: {
380:
381: }
382:
383: private void ipNum_TextChanged(object sender, EventArgs e)
384: {
385:
386: }
387:
388: private void fileToolStripMenuItem_Click(object sender, EventArgs e)
389: {
390:
391: }
392:
393: private void 使用说明ToolStripMenuItem_Click(object sender, EventArgs e)
394: {
395: MessageBox.Show("");
396: }
397:
398: private void 文本规则ToolStripMenuItem_Click(object sender, EventArgs e)
399: {
400: MessageBox.Show("上传数据包为TXT格式!");
401: }
402:
403: private void 联系ToolStripMenuItem_Click(object sender, EventArgs e)
404: {
405: MessageBox.Show("如果问题可联系sharexie、lesliezhang!");
406: }
407:
408: private void 关于ToolStripMenuItem_Click(object sender, EventArgs e)
409: {
410: MessageBox.Show("本软件为数据作弊分包处理,版本v1.0.0");
411: }
412:
413: private void 个数规则ToolStripMenuItem_Click(object sender, EventArgs e)
414: {
415: MessageBox.Show("个数设置为很大(超过数据总量),表示不对当前列过滤。");
416: }
417:
418: private void 时间编号ToolStripMenuItem_Click(object sender, EventArgs e)
419: {
420: MessageBox.Show("时间标号方便提取干净数据和灰名单。");
421: }
422: }
423: }