C# winfrom 寫的一個搜索助手,可以按照標題和內容搜索,指定目錄後,遍歷搜索文件和子目,現在只寫了支持.DOC.DOCX.XLS.XLSX.PPT.PPTX.PDF.HTML.HTM.TXT等格式的文件搜索,讀取execl 內容使用的是NPOI組件,doc,html,txt 格式的使用Str ...
C# winfrom 寫的一個搜索助手,可以按照標題和內容搜索,指定目錄後,遍歷搜索文件和子目,現在只寫了支持.DOC.DOCX.XLS.XLSX.PPT.PPTX.PDF.HTML.HTM.TXT等格式的文件搜索,讀取execl 內容使用的是NPOI組件,doc,html,txt 格式的使用StreamReader 流文件讀取方式,ppt,pdf使用的Spire組件。
直接上代碼
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Threading; using System.Security.AccessControl; using NPOI.SS.UserModel; using NPOI.HSSF.UserModel; using NPOI.XSSF.UserModel; using Spire.Presentation; using Spire.Pdf; namespace Search { public partial class formMain : Form { public formMain() { InitializeComponent(); } //選擇文件路徑 private void button1_Click(object sender, EventArgs e) { try { FolderBrowserDialog dialog = new FolderBrowserDialog(); dialog.Description = "請選擇文件路徑"; if (dialog.ShowDialog() == DialogResult.OK) { string foldPath = dialog.SelectedPath; textBox1.Text = foldPath; //把選擇路徑存儲在註冊表 Application.UserAppDataRegistry.SetValue("ZMJASearchPath", foldPath); } } catch (Exception err) { MessageBox.Show(err.Message); } } private void button2_Click(object sender, EventArgs e) { try { string foldPath = textBox1.Text; if (string.IsNullOrEmpty(foldPath)) { MessageBox.Show("請選擇文件路徑!"); return; } string searckkey = textBox2.Text; if (string.IsNullOrEmpty(searckkey)) { MessageBox.Show("請輸入搜索關鍵字!"); return; } string extension = comboBox1.Text; if (!string.IsNullOrEmpty(extension)) { extension = extension.ToUpper(); switch (extension) { case ".HTML": extension = ".HTML.HTM"; break; case ".DOC": extension = ".DOC.DOCX"; break; case ".XLS": extension = ".XLS.XLSX"; break; case ".PPT": extension = ".PPT.PPTX"; break; default: break; } } else { extension = ".DOC.DOCX.XLS.XLSX.PPT.PPTX.PDF.HTML.HTM.TXT"; } dataGridView1.Rows.Clear(); listDirectory(@foldPath, extension, comboBox2.Text, searckkey); lbmessage.Text = ""; MessageBox.Show("搜索完畢"); } catch (Exception err) { MessageBox.Show(err.Message); } } /// <summary> /// 列出path路徑對應的文件夾中的子文件夾和文件 /// 然後再遞歸列出子文件夾內的文件和文件夾 /// </summary> /// <param name="path">需要搜索文件夾的路徑</param> public void listDirectory(string path,string extension, string coding,string searckkey) { DirectoryInfo theFolder = new DirectoryInfo(@path); DirectorySecurity s = new DirectorySecurity(path, AccessControlSections.Access); //判斷目錄是否 可以訪問 if (!s.AreAccessRulesProtected) { foreach (FileInfo file in theFolder.GetFiles()) { if (string.IsNullOrEmpty(extension) || extension.Contains(file.Extension.ToUpper())) { lbmessage.Text = "正在搜索文件:" + path + "\\" + file.Name; Application.DoEvents(); #region 僅檢索標題 if (comboBox3.Text == "僅標題") { if (file.Name.Contains(searckkey)) { int index = this.dataGridView1.Rows.Add(); this.dataGridView1.Rows[index].Cells[0].Value = index + 1; this.dataGridView1.Rows[index].Cells[1].Value = file.Name; this.dataGridView1.Rows[index].Cells[2].Value = path + "\\" + file.Name; break; } } #endregion #region 標題和內容都檢索 else { #region 檢索判斷標題 //預設檢索 先搜索標題是否有,如果有,則退出迴圈,如果沒有,再檢索內容 if (file.Name.Contains(searckkey)) { int index = this.dataGridView1.Rows.Add(); this.dataGridView1.Rows[index].Cells[0].Value = index + 1; this.dataGridView1.Rows[index].Cells[1].Value = file.Name; this.dataGridView1.Rows[index].Cells[2].Value = path + "\\" + file.Name; break; } #endregion using (FileStream fs = new FileStream(path + "\\" + file.Name, FileMode.Open, FileAccess.Read)) { #region 讀取Execl if (file.Extension.ToUpper().Contains(".XLS")) { try { IWorkbook workbook = null;//全局workbook ISheet sheet;//sheet switch (file.Extension) { //xls是03,用HSSFWorkbook打開,.xlsx是07或者10用XSSFWorkbook打開 case ".xls": workbook = new HSSFWorkbook(fs); break; case ".xlsx": workbook = new XSSFWorkbook(fs); break; default: break; } fs.Close();//關閉文件流 if (workbook != null) { int count = workbook.NumberOfSheets; bool bo = false; //bo初始化為假 for (int index = 0; index < count; index++) { if (bo)//如果bo為真 break;//退出第一層迴圈 sheet = workbook.GetSheetAt(index);//讀取到指定的sheet //遍歷讀取cell for (int i = sheet.FirstRowNum; i <= sheet.LastRowNum; i++) { if (bo)//如果bo為真 break;//退出第二層迴圈 IRow row = sheet.GetRow(i);//得到一行 if (row != null) { for (int j = row.FirstCellNum; j < row.LastCellNum; j++) { ICell cell = row.GetCell(j);//得到cell if (cell != null)//如果cell為null,則賦值為空 { if (row.GetCell(j).ToString().Contains(searckkey)) { int GridIndex = this.dataGridView1.Rows.Add(); this.dataGridView1.Rows[GridIndex].Cells[0].Value = GridIndex + 1; this.dataGridView1.Rows[GridIndex].Cells[1].Value = file.Name; this.dataGridView1.Rows[GridIndex].Cells[2].Value = path + "\\" + file.Name; bo = true;//bo賦為真 break;//退出第三層迴圈 } } } } } } } //釋放資源 workbook = null; sheet = null; } catch (Exception err) { //MessageBox.Show(err.Message); } } #endregion #region 讀取ppt內容 else if (file.Extension.ToUpper().Contains(".PPT")) { try { //初始化一個Presentation類實例,並載入文檔 Presentation ppt = new Presentation(); ppt.LoadFromFile(path + "\\" + file.Name); bool bo = false; foreach (ISlide slide in ppt.Slides) { if (bo)//如果bo為真 break;//退出第一層迴圈 foreach (Spire.Presentation.IShape shape in slide.Shapes) { if (bo)//如果bo為真 break;//退出第一層迴圈 if (shape is IAutoShape) { foreach (TextParagraph tp in (shape as IAutoShape).TextFrame.Paragraphs) { if (tp.Text.Contains(searckkey)) { int GridIndex = this.dataGridView1.Rows.Add(); this.dataGridView1.Rows[GridIndex].Cells[0].Value = GridIndex + 1; this.dataGridView1.Rows[GridIndex].Cells[1].Value = file.Name; this.dataGridView1.Rows[GridIndex].Cells[2].Value = path + "\\" + file.Name; bo = true;//bo賦為真 break;//退出第三層迴圈 } } } } } ppt = null; //釋放資源 } catch (Exception err) { //MessageBox.Show(err.Message); } } #endregion #region 讀取pdf文件 else if (file.Extension.ToUpper().Contains(".PDF")) { try { PdfDocument pdf= new PdfDocument(); pdf.LoadFromFile(@path + "\\" + file.Name); foreach (PdfPageBase page in pdf.Pages) { string content = page.ExtractText(); if (content.Contains(searckkey)) { int GridIndex = this.dataGridView1.Rows.Add(); this.dataGridView1.Rows[GridIndex].Cells[0].Value = GridIndex + 1; this.dataGridView1.Rows[GridIndex].Cells[1].Value = file.Name; this.dataGridView1.Rows[GridIndex].Cells[2].Value = path + "\\" + file.Name; break; } } pdf = null;//釋放資源 } catch (Exception err) { } } #endregion #region 讀取其他文本文件 else { Encoding codingType = Encoding.Default; if (!string.IsNullOrEmpty(coding)) { codingType = Encoding.GetEncoding(coding.ToUpper()); } else { codingType = common.GetType(path + "\\" + file.Name); } StreamReader sr = new StreamReader(fs, codingType); String str; while ((str = sr.ReadLine()) != null) { if (str.Contains(searckkey)) { int index = this.dataGridView1.Rows.Add(); this.dataGridView1.Rows[index].Cells[0].Value = index + 1; this.dataGridView1.Rows[index].Cells[1].Value = file.Name; this.dataGridView1.Rows[index].Cells[2].Value = path + "\\" + file.Name; sr.Close(); fs.Close(); break; } } } #endregion } } #endregion } } } //遍歷文件夾 foreach (DirectoryInfo NextFolder in theFolder.GetDirectories()) { if ((NextFolder.Attributes & FileAttributes.Hidden) != FileAttributes.Hidden) { listDirectory(NextFolder.FullName,extension, coding,searckkey); } } } private void OpenFolderAndSelectFile(String fileFullName) { System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo("Explorer.exe"); psi.Arguments = "/e,/select," + fileFullName; System.Diagnostics.Process.Start(psi); } private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e) { } //刪除文件,這裡是一個偽刪除了,直接把文件移動到deleteData文件夾中,如果需要刪除手動刪除 private void button3_Click(object sender, EventArgs e) { try { int count = 0; int totalCount = dataGridView1.RowCount; string foldPath = textBox1.Text; string filderPath = @foldPath + "\\DeleteData"; string fileName = ""; if (Directory.Exists(filderPath) == false) { //如果不存 Directory.CreateDirectory(filderPath); } for (int i = 0; i < dataGridView1.RowCount; i++) { lbmessage.Text = "正在刪除文件:" + dataGridView1.Rows[i].Cells[2].Value.ToString(); Application.DoEvents(); count += 1; fileName = dataGridView1.Rows[i].Cells[1].Value.ToString(); File.Move(dataGridView1.Rows[i].Cells[2].Value.ToString(), filderPath + "\\" + fileName); } dataGridView1.Rows.Clear(); lbmessage.Text = ""; MessageBox.Show("刪除完畢"); } catch (Exception err) { MessageBox.Show(err.Message); } finally { lbmessage.Text = ""; } } //清空列表 private void button4_Click(object sender, EventArgs e) { dataGridView1.Rows.Clear(); } private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { string extension = comboBox1.Text; if (!string.IsNullOrEmpty(extension)) { extension = extension.ToUpper(); switch (extension) { case ".HTML": comboBox2.SelectedIndex = comboBox2.Items.IndexOf("UTF-8"); break; case ".DOC": comboBox2.SelectedIndex = comboBox2.Items.IndexOf("Unicode"); break; default: break; } } } //預設載入 private void formMain_Load(object sender, EventArgs e) { //預設是全部搜索模式 comboBox3.SelectedText = "全部"; //從註冊表把選擇路徑讀取出來 textBox1.Text = Application.UserAppDataRegistry.GetValue("ZMJASearchPath") as string; } //雙擊單元格打開文件所在位置 private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e) { try { if (e.ColumnIndex < 0 || e.RowIndex < 0) { MessageBox.Show("請選擇要打開的文件"); return; } int index = dataGridView1.CurrentCell.RowIndex; System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo("Explorer.exe"); psi.Arguments = "/e,/select," + dataGridView1.Rows[index].Cells[2].Value.ToString(); System.Diagnostics.Process.Start(psi); } catch (Exception err) { MessageBox.Show(err.Message); } } //右鍵快捷菜單打開文件所在位置 private void 打開文件所在位置ToolStripMenuItem_Click(object sender, EventArgs e) { try { if (dataGridView1.CurrentRow == null) { MessageBox.Show("請選擇要打開的文件"); return; } int index = dataGridView1.CurrentCell.RowIndex; System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo("Explorer.exe"); psi.Arguments = "/e,/select," + dataGridView1.Rows[index].Cells[2].Value.ToString(); System.Diagnostics.Process.Start(psi); } catch (Exception err) { MessageBox.Show(err.Message); } } //雙擊文本框選擇路徑 private void textBox1_DoubleClick(object sender, EventArgs e) { try { FolderBrowserDialog dialog = new FolderBrowserDialog(); dialog.Description = "請選擇文件路徑"; if (dialog.ShowDialog() == DialogResult.OK) { string foldPath = dialog.SelectedPath; textBox1.Text = foldPath; //把選擇路徑存儲在註冊表 Application.UserAppDataRegistry.SetValue("ZMJASearchPath", foldPath); } } catch (Exception err) { MessageBox.Show(err.Message); } } } }
參考博客園裡獲取文件編碼格式的類
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Search { public class common { //編碼問題目前為止,基本上沒人解決,就連windows的IE的自動識別有時還識別錯編碼呢 //如果文件有BOM則判斷,如果沒有就用系統預設編碼,缺點:沒有BOM的非系統編碼文件會顯示亂碼。 //調用方法: common.GetType(filename) public static System.Text.Encoding GetType(string FILE_NAME) { using (FileStream fs = new FileStream(FILE_NAME, FileMode.Open, FileAccess.Read)) { System.Text.Encoding r = GetType(fs); fs.Close(); return r; } } /// <summary> /// 通過給定的文件流,判斷文件的編碼類型 /// </summary> /// <param name="fs">文件流</param> /// <returns>文件的編碼類型</returns> public static System.Text.Encoding GetType(FileStream fs) { byte[] Unicode = new byte[] { 0xFF, 0xFE, 0x41 }; byte[] UnicodeBIG = new byte[] { 0xFE, 0xFF, 0x00 }; byte[] UTF8 = new byte[] { 0xEF, 0xBB, 0xBF }; //帶BOM Encoding reVal = Encoding.Default; BinaryReader r = new BinaryReader(fs, System.Text.Encoding.Default); int i; int.TryParse(fs.Length.ToString(), out i); byte[] ss = r.ReadBytes(i); if (IsUTF8Bytes(ss) || (ss[0] == 0xEF && ss[1] == 0xBB && ss[2] == 0xBF)) { reVal = Encoding.UTF8; } else if (ss[0] == 0xFE && ss[1] == 0xFF && ss[2] == 0x00) { reVal = Encoding.BigEndianUnicode; } else if (ss[0] == 0xFF && ss[1] == 0xFE && ss[2] == 0x41) { reVal = Encoding.Unicode; } r.Close(); return reVal; } /// <summary> /// 判斷是否是不帶 BOM 的 UTF8 格式 /// </summary> /// <param name=“data“></param> /// <returns></returns> private static bool IsUTF8Bytes(byte[] data) { int charByteCounter = 1; //計算當前正分析的字元應還有的位元組數 byte curByte; //當前分析的位元組. for (int i = 0; i < data.Length; i++) { curByte = data[i]; if (charByteCounter == 1) { if (curByte >= 0x80) { //判斷當前 while (((curByte <<= 1) & 0x80) != 0) { charByteCounter++; } //標記位首位若為非0 則至少以2個1開始 如:110XXXXX...........1111110X if (charByteCounter == 1 || charByteCounter > 6) { return false; } } } else { //若是UTF-8 此時第一位必須為1 if ((curByte & 0xC0) != 0x80) { return false; } charByteCounter--; } } if (charByteCounter > 1) { throw new Exception("非預期的byte格式"); } return true; } } }