C# winfrom 写的一个搜索助手,可以按照标题和内容搜索,支持doc,xls,ppt,pdf,txt等格式的文件搜索
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; } } }