C#编写文件搜索器

介绍 在装有Vista的机器上。我想通过一个给定的字符串来搜索我硬盘上的一个文件,该文件内容包含这个字符串序列,资源管理器是做不到的。因此,我就决定自己写吧。然后就写成这样了。。 我做了什么 你必须输入一个选择一个搜索目录,这样程序才知道在哪搜索文件/目录,如果你选上了“包含子目录”复选框,程序就会递归地搜索指定目录的子目录,指定的文件名可以是像 “.wav;.mp3;Christma??ree.*” 这样的字符串,程序将会列出所有的文件/目录匹配这些文件名 你也可以使用一些限制条件来限制找到的项目,每一个限制条件可以通过选上复选框来激活,限制条件的参数可以在右边选中就行了。 1. “Files newer than”将会列出LastWriteTime(上次修改时间)晚于指定时间的文件 2. “Files newer than”将会列出LastWriteTime(上次修改时间)早于指定时间的文件 3. “Files containing the string"仅仅列出包含字符串参数的文件。 程序将会把字符串转换成字节序列,可以使用ASCII或者Unicode编码,取决于你的选择,然后搜索每一个出现这个字节序列的文件。 点击Start(开始)按钮就开始搜索了。找到的项目会列在下面,如果搜索时间太长了。你可以点击Stop(停止)来停止搜索。 如果你双击下面的一个文件。不是文件夹哦,程序将会根据关联程序打开该文件 如果你邮件一个项目,然后选择“Open Containing Folder”(打开包含文件夹)将会在资源管理器里打开包含该项目的文件夹 如果你想要把搜索结果保存到一个文本文件。输入个分隔符分隔项目,然后点击“Write results to text file…”(保存结果到文本…) 使用代码 1. MainWindow处理所有的界面事务 2. Searcher类提供了业务逻辑,用来搜索FileSystemInfo对象 当用户点击Start(开始)按钮,Searcher.Start 方法就会执行,该方法开启了一个名为SearchThread 的新线程,这个线程搜索文件/目录,匹配用户输入的参数,如果找到了一个匹配的FileSystemInfo对象,它就出发一个异步的FoundInfo 事件,然后MainWindow就可以从FoundInfoEventArgs中解出FileSystemInfo对象,然后更新结果列表,当线程结束的时候,将m_thread成员对象设置为null,每一次Searcher.Start 执行的时候都会检测m_thread是否为null,因此同时不会有两个线程在运行。 当用户点击Stop(停止)按钮的时候Searcher.Stop 方法被执行,然后设置m_stop 成员为true, Searchthread会注意到这个改变。注意本操作是线程安全的。因为布尔变量只需要一步就操作完成了 重要:在Searcher_FoundInfo 事件处理中,MainWindow使用Invoke方法通过代理来调用this_FoundInfo 方法。通过这个方法,MainWindow是的更新结果列表的代码在MainWindow的线程里执行,而不是在Searcher的线程里,直接调用this_FoundInfo 方法会引发程序崩溃,因为Searcher_FoundInfo 事件处理和图形界面控件不同步。 private delegate void FoundInfoSyncHandler(FoundInfoEventArgs e); private FoundInfoSyncHandler FoundInfo; ... private void MainWindow_Load(object sender, EventArgs e) { ... this.FoundInfo += new FoundInfoSyncHandler(this_FoundInfo); ... } ... private void Searcher_FoundInfo(FoundInfoEventArgs e) { if (!m_closing) { this.Invoke(FoundInfo, new object[] { e }); } } private void this_FoundInfo(FoundInfoEventArgs e) { CreateResultsListItem(e.Info); } CreateResultsListItem 方法创建并添加一个ListViewItem 到结果列表中,然后展示FilesystemInfo 对象包含的数据,FileSystemInfo 可以是FileInfo 或是DirectoryInfo ,取决于Searcher 找到的结果, is操作符可以用来判断对象的类型,如果是FileInfo独享,列表还会以KB为单位显示文件大小 ListViewItem.ListViewSubItem lvsi = new ListViewItem.ListViewSubItem(); if (info is FileInfo) { lvsi.Text = GetBytesStringKB(((FileInfo)info).Length); } else { lvsi.Text = ""; } 当Searcher 线程结束的时候,触发ThreadEnded 事件,因此,MainWindow可以注意到搜索结束,Searcher_ThreadEnded 事件处理句柄使用和Searcher_FoundInfo一样的方式调用Invoke方法。 private delegate void ThreadEndedSyncHandler(ThreadEndedEventArgs e); private ThreadEndedSyncHandler ThreadEnded; ... private void MainWindow_Load(object sender, EventArgs e) { ... this.ThreadEnded += new ThreadEndedSyncHandler(this_ThreadEnded); ... } ... private void Searcher_ThreadEnded(ThreadEndedEventArgs e) { if (!m_closing) { this.Invoke(ThreadEnded, new object[] { e }); } } private void this_ThreadEnded(ThreadEndedEventArgs e) { EnableButtons(); if (!e.Success) { MessageBox.Show(e.ErrorMsg, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } Demo下载 FileSearcher 许可 本文包括源代码和文件在CPOL下授权 ...

2012-10-01 · 1 min · bystander

ListView布局管理器

介绍 使用ListViewLayoutManager 可以控制ListView/GridView列的布局 固定列宽:有着固定列宽的列 范围列宽:有着最小最大宽度的列 比例列宽:成比例的列宽 范围列宽可以限制列的宽度,也包括填充列的剩余可视区域。 据我们了解的Html中的表格和Grid空间。比例列以一个百分比来定义列宽,以下几个因素共同确定了比例列的宽度。 垂直ListView滚动条的可视与否 ListView控件宽度的改变 非比例列宽度的改变 本程序支持通过XAML或是后台代码来控制ListView。如果通过XAML来控制。则允许ListViewLayoutManager 被附加到一个存在的ListView控件上。 ConverterGridColumn 类通过接口IValueConverter 提供了对象绑定。使用ImageGridViewColumn 类则允许通过DataTemplate(数据模板)将列显示成图片等。 在 User Setting Applied中,我展示了如何固定ListViewlieder顺序和大小 XAML中ListView/GridView布局 固定列 下面的例子展示了通过XAML使用固定列宽控制列 <ListView Name="MyListView" ctrl:ListViewLayoutManager.Enabled="true"> <ListView.View> <GridView> <GridViewColumn DisplayMemberBinding="{Binding Path=Name}" ctrl:FixedColumn.Width="100" Header="Name" /> <GridViewColumn DisplayMemberBinding="{Binding Path=City}" ctrl:FixedColumn.Width="300" Header="City" /> </GridView> </ListView.View> </ListView> 设置附加到ListView控件上的ListViewLayoutManager 的Enabled属性为True。然后FixedColumn.Width 就会阻止鼠标拖动改变列的宽度。 比例列 下面的例子展示了使用XAML通过比例来控制列 对比Grid控件的RowDefinition.Width 属性,ProportionalColumn.Width会计算百分比。简单来说,就是上面的例子中Name列会占到总宽度的25%,而City列占到75%。 与固定列相似。鼠标将不能改变列的宽度。 范围列 下面的例子展示了使用XAML通过最小/最小宽度来控制列 第一个范围列的IsFillColumn 属性被设置为True,因此将会自动改变大小来填满剩余的空间,而如果ListView包含一个比例列的话,范围列将不会填充 通过鼠标可以拖动范围列的宽度。鼠标指针会有一些提示。。 组合使用 在真实的世界里。组合使用很普遍。他们的顺序可以多种多样。 使用后台代码控制ListView/GridView布局 ListView listView = new ListView(); new ListViewLayoutManager( listView ); // attach the layout manager GridView gridView = new GridView(); gridView.Columns.Add( FixedColumn.ApplyWidth( new MyGridViewColumn( "State" ), 25 ) ); gridView.Columns.Add( RangeColumn.ApplyWidth( new MyGridViewColumn( "Name" ), 100, 150, 200 ) ); // 100...200 gridView.Columns.Add( ProportionalColumn.ApplyWidth( new MyGridViewColumn( "City" ), 1 ) ); // 33% gridView.Columns.Add( ProportionalColumn.ApplyWidth( new MyGridViewColumn( "Country" ), 2 ) ); // 66% listView.View = gridView; 定制列的效果 类ConverterGridColumn 作为一个基类,用来绑定列到独立的对象。 ...

2012-09-29 · 3 min · bystander

JavaCC入门教程及相关资源

今天下午翻译了一篇简单的文章后。就去看JavaCC的东西了。。然后就找到了一篇入门教程 然后之前我是找到了一篇翻译过来的的某熊的战略储备基地 从头到尾读了一遍英文的。感觉还是英文的写的要好一些。建议对照着翻译看英文。JavaCC也就那么回事。。 同时在在这目测百慕大群岛的什么工程与应用科学学院找到了一些其他的文档。其中一篇是JavaCC-FAQ很好。基本上有关JavaCC的问题都有解释。 在FAQ里,看到了一个关于JJTree的介绍,写的不错。建议看看。 还有一个是国外某学校的编译原理课程的ppt下载,好象是以JavaCC作为工具的。还没认真看。 还有一篇JavaCC 研究与应用 ,写的平常。不过是中文版的。 最后。千万不要忘了官方文档。也包括你下载的JavaCC里面的Demo。。

2012-09-27 · 1 min · bystander

AvalonDock 2.0入门指南第一部分

AvalonDock 2.0可以用来为WPF创建一个类似Visual Studio的界面,深入理解如何使用AvalonDock进行开发是很重要的。 在这个入门指南里,我将演示如何开始使用AvalonDock,下面的文章都是基于2.0版本的。并且不能用于早期的版本。 AvalonDock是一个组合的布局模型,很多的控件都在视图上显示,一个DockingManager 类也显示在停靠区,用于可以拖拽文档和工具。 从下面这个截图中我们可以理解AvalonDock组件 DockingManager 这是AvalonDock中的核心控件,它将包含的窗格排序,处理飞出的窗格,还有浮动的窗口。在上面这个图中,DockingManager 对象包含了所有空间(WPF控件),从顶部的工具栏到底部的状态栏都算。同时。DockingManager 也可以处理保存和恢复布局。 LayoutPanel 这个面板用来管理在一个方向上的子窗口(通过Orientation属性来选择方向),并且在它们之间添加了一个大小调节控件,在一个Orientation属性是Horizontal(水平)的LayoutPanel 上,排列了三个窗格。一个LayoutAnchorablePane在左,一个LayoutDocumentPane在中间。一个LayoutDockablePane在右边。 LayoutDockablePane 这个布局元素包含一个LayoutAnchorable对象的集合。通过它用来管理想TabControl这样的控件,在上面的截图中,LayoutDockablePanes是在左边的’Strumenti’ 和 ‘Progetti’ (工具和项目) 和在右边的’Classi’ 和 ‘Proprieta’’ (类视图和属性视图)的容器,一个LayoutDockablePane可以自动隐藏,就像’Errori’(错误)和’Lista Azioni’(操作列表) and ‘Uscita’(输出)。并且LayoutDockablePane可以被拖动到DockingManager上,成为一个浮动窗口或者附着到它的父控件DockingManager的边缘上。 LayoutDocumentPane 通常包含文档(DocumentContent类型)的一种窗格,但是其实也可以包含像上面提到的工具视图和类视图这样的DockableContents。在一个文档里。LayoutDocumentPane 被放置在ResizingPanel(水平方向)里。ResizingPanel则是上卖弄提到的在两个DockablePane中间的区域。注意。文档窗格是不能被移动的。 LayoutAnchorable 一个停靠内容,是软件控件的容器,总是被包含在一个窗格里(LayoutAnchorablePane或是LayoutDocumentPane),在截图里。LayoutAnchorable是一类对象(包含一个SharpDevelop对象),工具对象,但是错误窗口(它处于自动隐藏状态,被好办在一个自动隐藏窗格里)不是。LayoutAnchorable就像它名字所暗示的那样。可以被从他的容器窗格里拖走。然后重新放置在一个存在的窗格里。或者是放置在父DockingManager的边缘,或者是放置在一个浮动窗口里(LayoutAnchorableFloatingWindow)。 LayoutDocument 是一个仅可以被寄宿到LayoutDocumentPane的内容。它是一个特殊的内容,因为不能被停靠到边缘。仅能被放置到LayoutDocumentPane里。或者浮动在一个LayoutDocumentFloatingWindow窗口里。在途中,DocumentContent对象是program.cs’ 或 ‘MainForm.cs’ 文件视图 **LayoutFloatingWindow **,是一个包含内容的窗口,当被拖动到一个DockingManager上面的时候,LayoutFloatingWindow(LayoutAnchorableFloatingWindow和LayoutDocumentFloatingWindow继承自他)集成在Window,总是包含一个窗格(LayoutAnchorablePane或是LayoutDocumentPane),窗格包含更多的内容(LayoutAnchorable或LayoutDocument),当用户对一个内容或是DockablePane执行拖拽,或者直接手工使用代码调用LayoutContent.Float()方法 LayoutFloatingWindow就被直接从DockingManager创建出来了。 LayoutPane 一个基类,LayoutDockablePane和LayoutDocumentPane继承自它。它为他们提供了一些共有的属性和方法。 LayoutContent 是LayoutAnchorable 和LayoutAnchorable类的父类。提供了共有的属性和方法。 理解布局元素是一些属于布局模型的类而不是属于视图是很重要的。因为,他们不是继承自FrameworkElement类,取而代之。AvalonDock包含了另一些类来展示这些组件的视图。这些类通常被命名为相关联的类名+Control字串。举个例子,在布局里创建的LayoutAnchorable创建了一个LayoutAnchorableControl(继承自FrameworkElement的类),并且绑定了LayoutAnchorableControl.Model 到这个LayoutAnchorable对象上。 每一个被创建的视图控件总是有着Model属性的布局元素。因此,重新设计一个相关视图控件的样式是可以的。 为了开始创建一个新的.net 4/.net 4.5的解决方案。并且添加对AvalonDock.dll的引用(可以直接添加也可以使用NuGet),然后添加AD命名空间到MainWindow.xaml中。 在根Grid下放置DockingManager组件和一个简单的布局。 <Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:avalonDock="http://avalondock.codeplex.com" Title="MainWindow" Height="434" Width="684"> <Grid> <avalonDock:DockingManager x:Name="dockingManager"> <avalonDock:LayoutRoot> <avalonDock:LayoutPanel Orientation="Horizontal"> <avalonDock:LayoutDocumentPane/> <avalonDock:LayoutAnchorablePane DockWidth="150"> <avalonDock:LayoutAnchorable Title="Sample Tool Pane"> <TextBox/> </avalonDock:LayoutAnchorable> </avalonDock:LayoutAnchorablePane> </avalonDock:LayoutPanel> <avalonDock:LayoutRoot.LeftSide> <avalonDock:LayoutAnchorSide> <avalonDock:LayoutAnchorGroup> <avalonDock:LayoutAnchorable Title="Autohidden Content"> <TextBox/> </avalonDock:LayoutAnchorable> </avalonDock:LayoutAnchorGroup> </avalonDock:LayoutAnchorSide> </avalonDock:LayoutRoot.LeftSide> </avalonDock:LayoutRoot> </avalonDock:DockingManager> </Grid> </Window> DockingManager是AvalonDock的核心类,他的责任就是创建管理布局。布局被定义成一个ILayoutElement的树。树的根由LayoutRoot类指定。LayoutRoot由一些基本的子树来构成。。 1.根面板的 根属性指向主 LayoutPanel,也是LayoutRoot的内容属性。 2.大体上讲,RightSide/LeftSide/TopSide/BottonSide是LayoutAnchorGroup对象的集合属性,他们表示了停靠管理器的四个边。停靠管理器的锚通常是隐藏的。当用户移动鼠标到这些区域的时候。就会在自动隐藏的窗口里显示出来。 3.FloatingWindows属性是FloatingWindow的集合。一个浮动窗口当用户拖动一个窗格(LayoutAnchorable或是LayoutDocument)的时候就被创建出来,这个集合可以被AvalonDock自动更新,但是用户依然可以通过调用LayoutContent的Float()方法来创建一个浮动窗口。 Hidden是一个Anchorable(停靠)对象的集合。默认情况下,当用户点击一个LayoutAnchorable对象的关闭按钮,AvalonDock隐藏它:通过从布局里移除停靠元素,并且把他放入Hidden集合,当用户想要再一次显示的时候,AD又把这个内容从隐藏集合里删除重新显示在他被隐藏的那个窗格里。 当使用布局树的时候,程序员可以创建任何复杂的界面,LayoutAnchorablePane的DockWidth和DockHeight属性可以被用来设置窗格的初始宽度和高度。而LayoutDocumentPane类通常则填满可用的空间。AvalonDock管理内容元素的宽度和高度以使得可以使用所有的可用空间。因此如果一个LayoutAnchorablePane被放置在一个LayoutPanel里,为LayoutAnchorablePane使用一个固定尺寸而为LayoutDocumentPane使用一个比例长度。也就是说为停靠对象使用了比例长度。 一个LayoutDocumentGroup/ LayoutAnchorableGroup类可以被用来包含更多的LayoutDocumentPane/ LayoutAnchorablePane,举个例子,让我们来改变上面的例子来实现更复杂的例子。 <Window x:Class="AvalonDock2Tutorial.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:avalonDock="http://avalondock.codeplex.com" Title="MainWindow" Height="350" Width="525"> <Grid> <avalonDock:DockingManager x:Name="dockingManager"> <avalonDock:LayoutRoot> <avalonDock:LayoutPanel Orientation="Horizontal"> <avalonDock:LayoutDocumentPaneGroup> <avalonDock:LayoutDocumentPane> <avalonDock:LayoutDocument Title="Doc1"> <TextBox/> </avalonDock:LayoutDocument> <avalonDock:LayoutDocument Title="Doc2"> <TextBox/> </avalonDock:LayoutDocument> </avalonDock:LayoutDocumentPane> <avalonDock:LayoutDocumentPane> <avalonDock:LayoutDocument Title="Doc3"> <TextBox/> </avalonDock:LayoutDocument> </avalonDock:LayoutDocumentPane> </avalonDock:LayoutDocumentPaneGroup> <avalonDock:LayoutAnchorablePaneGroup DockWidth="150" Orientation="Vertical"> <avalonDock:LayoutAnchorablePane> <avalonDock:LayoutAnchorable Title="Tool 1"> <TextBox/> </avalonDock:LayoutAnchorable> <avalonDock:LayoutAnchorable Title="Tool 2"> <TextBox/> </avalonDock:LayoutAnchorable> </avalonDock:LayoutAnchorablePane> <avalonDock:LayoutAnchorablePane> <avalonDock:LayoutAnchorable Title="Tool 3"> <TextBox/> </avalonDock:LayoutAnchorable> <avalonDock:LayoutAnchorable Title="Tool 4"> <TextBox/> </avalonDock:LayoutAnchorable> </avalonDock:LayoutAnchorablePane> </avalonDock:LayoutAnchorablePaneGroup> </avalonDock:LayoutPanel> <avalonDock:LayoutRoot.LeftSide> <avalonDock:LayoutAnchorSide> <avalonDock:LayoutAnchorGroup> <avalonDock:LayoutAnchorable Title="Autohidden Content"> <TextBox/> </avalonDock:LayoutAnchorable> </avalonDock:LayoutAnchorGroup> </avalonDock:LayoutAnchorSide> </avalonDock:LayoutRoot.LeftSide> </avalonDock:LayoutRoot> </avalonDock:DockingManager> </Grid> </Window> 运行这个工程你就可以重新排列内容了。移动他们到浮动窗口。为了更加熟悉AvalonDock,我建议你多试几次,然后重新排列内容实现更复杂的布局。 ...

2012-09-26 · 1 min · bystander

C# 网络编程系列

本系列来自博客园的Learning hard园友。每个博主都不容易,我这里只是给出一个索引,希望更多热爱技术的人能够看到。给分享者更多的鼓励和支持。 专题一:网络协议简介 专题二:HTTP协议详解 专题三:自定义Web服务器 专题四:自定义Web浏览器 专题五:TCP编程 专题六:UDP编程 专题七:UDP编程补充——UDP广播程序的实现 专题八:P2P编程 专题九:实现类似QQ的即时通信程序 专题十:实现简单的邮件收发器

2012-09-25 · 1 min · bystander

一个可定制的WPF任务对话框

今天实在看WPF揭秘的时候看到TaskDialog这个控件的。然后就去找了一下开源的代码。在codeproject上发现了这个,非常给力。。另外codeproject改版后很漂亮哦。 介绍: 这是用WPF实现Vista上TaskDialog效果的代码。 Messagbox消息框 通过调用重写的静态Show方法。TaskDialog就会表现的像一个Messagebox。他有四个文本类型的属性:Header(头部), Content(内容), Detail(更多), 和 Footer(底部),其实Detail是一个折叠的区域, 而Header和Footer还有一个icon属性(HeaderIcon和FooterIcon),除此之外,Header还有Background(背景)和Foreground(前景)属性 // TaskDialog.Show方法签名 public static TaskDialogResult Show( string title, string header, string content, string detail, string footer, TaskDialogButton button, TaskDialogResult defaultResult, TaskDialogIcon headerIcon, TaskDialogIcon footerIcon, Brush headerBackground, Brush headerForeground) // TaskDialog.Show 方法的一个例子 TaskDialog.Show("Task Dialog 测试", "消息框的标题文字", "消息框的内容部分. " + " 可以自适应内容.", "消息框的细节部分 " + "可以自适应内容", "消息框的底部.", TaskDialogButton.Ok, TaskDialogResult.None, TaskDialogIcon.Information, TaskDialogIcon.Shield, Brushes.White, Brushes.Navy); 定制TaskDialog 使用静态的Show方法。Header, Content, Detail, 和Footer 就限制了只能传递字符串作为值了。 为了定义这个对话框,你先创建TaskDialog类的一个对象,然后分别设置一下各个属性,最后调用Show方法就可以了 // TaskDialog 实例化例子 TaskDialog dialog = new TaskDialog(); dialog.title: = "TaskDialog example"; dialog.HeaderIcon = TaskDialogIcon.Warning; dialog.SystemSound = TaskDialogSound.Exclamation; // header 属性设置 dialog.Header = "This is the Header."; dialog.HeaderBackground = Brushes.DarkGray; dialog.HeaderForeground = Brushes.White; // Content, Detail 和 Footer属性设置 dialog.Content = "This is the content"; dialog.Detail = "This is the detail"; dialog.Footer = "this is the Footer"; dialog.Show(); TaskDialog控件派生自HeaderedContentControl类,因为从HeaderedContentControl类可以获得Header和Content属性,TaskDialog仅仅是添加了Detail和Footer属性,这些属性是Object类型,并且有他们自己的template(模板)属性HeaderTemplate, ContentTemplate, DetailTemplate, 和 FooterTemplate),TaskDialog类对于文本内容有着缺省的数据模板,当然你也可以用那四个模板来替换,这样你就可以以你喜欢的任何方式来格式化文本了。下面这个图展示了通过斜体和下划线来格式化文本。 图2 //为上面这个图的content属性的 DataTemplate 模板 <DataTemplate x:Key="_customContentDataTemplate"> <TextBlock Text="{Binding Content, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Controls:TaskDialog}}}" FontStyle="Italic" TextDecorations="Underline" TextWrapping="Wrap"/> </DataTemplate> 因为Header,Content,Detail和Footer是object类型,因此不再受到只能是文本的限制了,你可以防止你喜欢的任何类型到TaskDialog,下面这个例子中的TaskDialog是不是很像UAC的提示呢。这里Content属性是一个UserControl类型,放置了一个图片和一些文本还有两个CommandButtons(都是普通的按钮。。不过添加了一些定制的样式,再加了Header属性) ...

2012-09-24 · 1 min · bystander

Html解析工具-HtmlAgilityPack

这个工具是在暑假的时候发现的。但是最后没用这个工具。不过,这个工具可是非常强悍的。。 HtmlAgilityPack主要就是解析DOM的。常用的基础类其实不多,对解析DOM来说,就只有HtmlDocument和HtmlNode这两个常用的类,还有一个 HtmlNodeCollection集合类。我给出一个抓取我博客首页文章的例子。看代码可能更清楚一点。你可以去看看压缩包里提供的文档。 xpath如果自己写表达式比较麻烦。所以我还找到了这个HtmlAgilityPack提供了的一个xpath辅助工具-HAPExplorer。都给出了地址。 首先看我的例子,抓取我博客的首页文章: using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Diagnostics; using System.Threading.Tasks; using System.IO; using System.Data; using System.Data.SqlClient; using HtmlAgilityPack; namespace leaver { class Program { static void Main(string[] args) { HtmlWeb web = new HtmlWeb(); HtmlDocument doc = web.Load("http://leaver.me/"); HtmlNode node = doc.GetElementbyId("content"); StreamWriter sw = File.CreateText("leaver.txt"); //从根节点选中class=hfeed的节点 string cfeed = node.SelectSingleNode("/html[1]/body[1]/div[1]/div[1]/div[2]/div[1]/div[1]").OuterHtml; HtmlNode hfeed = HtmlNode.CreateNode(cfeed); foreach (HtmlNode child in hfeed.ChildNodes) { if (child.Attributes["id"] == null || child.Attributes["id"].Value.Substring(0, 2) != "po") continue; HtmlNode hn = HtmlNode.CreateNode(child.OuterHtml); Write(sw, String.Format("标题:{0}", hn.SelectSingleNode("//*[@class=\"entry-title\"]").InnerText)); Write(sw, String.Format("日期:{0}", hn.SelectSingleNode("//*[@class=\"byline\"]").InnerText)); Write(sw, String.Format("摘要:{0}", hn.SelectSingleNode("//*[@class=\"entry-summary\"]").InnerText)); Write(sw, "----------------------------------------"); } sw.Close(); Console.ReadLine(); } static void Write(StreamWriter writer, string str) { Console.WriteLine(str); writer.WriteLine(str); } } } 程序运行结果: xpath表达式的具体书写都是需要分析你需要解析的网站源码的。。。。 xpath辅助工具的界面: 下载:HtmlAgilityPack 下载:HAPExplorer

2012-09-22 · 1 min · bystander

《商务智能与数据挖掘-谢邦昌》第三章读书笔记

3.数据挖掘 3.1定义 数据挖掘是指找寻隐藏在数据中的信息,如趋势。特征及相关性的过程。也就是从数据中发掘信息或知识(Knowledge Discovery in Database)。也有人称之为数据考古学。。记住,它不是一个无所不能的软件或是一种技术,他是一种结合数种专业技术的应用。数据挖掘工具从数据中发掘出个各种假设。但是并不帮你查证。确认这些假设。也不帮你判断这些假设是否有价值。 3.2数据挖掘的功能 1.分类(Classification),按照分析对象的属性进行分门别类加以定义。建立类组(Class)。例如划分银行信用申请者的风险属性,使用的技术有决策树(Decision Tree),记忆基础推理(memory-based reasoning) 2.估计(Estimation),根据既有连续性数值的相关属性数据。以获知某一属性未知值。。例如按照信用申请者的教育程度,行为估计其的信用卡缴费量。使用的技术包括相关分析,回归分析及神经网络算法。 3.预测(Prediction)根据对象属性的过去观察值来估计该属性未来值。比如根据顾客过去刷卡消费量来预测其未来刷卡消费量。使用的技术包括回归分析,时间序列分析,神经网络。 4.关联分组(Affinity Grouping)从所有对象决定哪些相关对象放在一起销售。比如那个啤酒和尿不湿。。在客户营销系统上,此功能用来确定交叉销售。。 5.聚类(Clustering),将异质总体中区分为特征相近的同质类组。目的是将组和组之间的差异辨识出来。并对个别组内相似样本进行挑选。 3.3数据挖掘的步骤 1.理解数据和数据所代表的含义(Data Understanding) 2.获取相关知识和技术(Domain Knowledge Acquisition) 3.整合和检查数据(Integration and Checking) 4.去除错误或不一致的数据(Data Cleaning) 5.建模与假设(Model and Hypothesis Development) 6.数据挖掘运行(Running) 7.测试与验证所挖掘的数据(Testing and Verification) 8.解释与使用数据(Interpretation and Use) 3.4数据挖掘建模的标准CRISP-DM CRISP-DM模型强调完整的数据挖掘过程,不能只针对数据整理、数据呈现、数据分析以及构建模型,还需要对企业的需求问题进行了解,同时,后期对模型进行评价和模型的延伸应用,也是一个完整的数据挖掘过程不可或缺的要素。 CRISP-DM分为六个阶段(phase)和四个层次(level),分别简介如下: 1. 商业理解(Business Understanding) 本阶段主要的工作是要针对企业问题以及企业需求进行了解确认,针对不同的需求做深入的了解,将其转换成数据挖掘的问题,并拟定初步构想。在此阶段中,需要与企业进行讨论,以确定分析者可以对于问题有非常清楚的了解,只有这样才可以正确地针对问题拟定分析过程。 2. 数据理解(Data Understanding) 这部分包含建立数据库与分析数据。在此阶段必须收集初步数据,然后了解数据的内涵与特性,选择要进行数据挖掘所必须的数据,然后进行数据整理及评估数据的质量,必要时再将分属不同数据库的数据加以合并及整合。数据库建立完成后再进行数据分析,找出影响预测最大的数据。 3. 数据预处理(Data Preparation) 此步骤和第二步数据理解是数据处理的核心,这是建立模型之前的最后一步数据准备工作。数据预处理任务很可能要执行多次,并且没有任何规定的顺序。 4. 建立模型(Modeling) 针对已预处理过的数据加以分析,配合各种技术方法加以应用,针对既有数据建构出模型,替企业解决问题;面对同一种问题,会有多种可以使用的分析技术,但是每一种分析技术却对数据有些限制及要求,因此需要回到数据前置处理的阶段,来重新转换需要的变量数据加以分析。 5. 评价和解释(Evaluation) 从数据分析的观点看,在开始进入这个阶段时已经建立了看似是高质量的模型,但在实际应用中,随着应用数据的不同,模型的准确率肯定会变化。这里,一个关键的目的是确定是否有某些重要的商业问题还没有充分地考虑。在这个阶段的结尾,应该获得对数据挖掘结果的判定。 6. 实施(Deployment) 一般而言,创建模型完成并不意味着项目结束。模型建立并经验证之后,可以有两种主要的使用方法。一种是提供给决策人员做参考,由他察看和分析这个模型之后提出行动方案建议;另一种是把此模型应用到不同的数据集上。此外,在应用了模型之后,当然还要不断监控它的效果。 四个层次分别为阶段(phase)、一般任务(generic task)、专项任务(specialized task)、流程实例(process instance)。每个阶段由若干一般任务组成,每个一般任务又实施若干专项任务,每个专项任务由若干流程实例来完成。其中,上两层独立于具体数据挖掘方法,即是一般数据挖掘项目均需实施的步骤(What to do?),这两层的任务将结合具体数据挖掘项目的“上下文”(context)映像到下两层的具体任务和过程。所谓项目的“上下文”是指项目开发中密切相关、需要综合考虑的一些关键问题,如应用领域、数据挖掘问题类型、技术难点、工具及其提供的技术等。

2012-09-21 · 1 min · bystander

《商务智能与数据挖掘-谢邦昌》第二章读书笔记

2.数据仓库 数据仓库名字上来看是很好理解的。他与传统的数据库的不同在于。传统的数据库是未经整理后的一大堆数据集。而数据仓库是从数据库中萃取出来。经过整理,规划,建构而成的一个有系统的数据库的子集合。 2.1数据仓库特点: 数据仓库的四个特点。 1.面向主题(Subject Orient)。数据建立的着重点就是在于以重要的主题组件作为核心。作为建构的方向。数据需求者只要把谣言觉得相关主题数据,从数据库中攫取,整合之后就可以做研究之用。 2.整合性(Integrated)各应用系统的数据需经过整合。以便利执行相关分析操作 3.长期性(Time Variance) 为了执行趋势的分析。数据仓库系统需保留1-10年的历史数据。这与数据库为日常性的数据有所不同。 4.稳定性(Non-Volatile)数据库可以被随时修改,但数据仓库基本上不会大动。只有内部人员会定期修改。但频率不会太多。也不允许用户做更新的动作。 由于以上的几个特点。数据仓库必须通过一连串的程序才可建立。而不是说即买即用。。 2.2数据仓库架构 数据源->整体数据仓库->部门性数据仓库->查询工具->终端用户 数据仓库的建设过程: 专业顾问通过与企业进行需求访谈,建立数据仓库的model,然后将企业内各种数据整合到数据库中,并建立前端分析数据的工具以及管理工具,这样的过程即为建立数据仓库的基本过程。 1.设计(Design) 即数据仓库的数据Model设计,这部分是最重要的,若Model设计的不够周全或布里希那个,不管之后的报表设计如何精美,也可能跑出错误的信息。这也是需要有经验的专业顾问建立数据仓库的一个重要原因。 2.整合(Integrate)即数据的整合转换过程,包含数据解释(Data Extraction) ,数据转换(Data Transformation)数据清理(Data Cleaning),数据加载(Data Loading)将各种来源的数据整理,转换并加载数据仓库中,程序编写较为繁杂,自动化处理困难,经常需要人工参与操作,大约占掉该项目60-70%的时间和人力。 3.可视化(Visualize)即前端呈现给用户看的形式,例如数据挖掘(Data Mining) 即OLAP工具,用以呈现分析过的数据形式。 4.调度(Administration)为管理的工具。 2.3建立数据仓库的原因和目的 提高企业的竞争能力,降低成本,提高客户满意度。创造利润。

2012-09-20 · 1 min · bystander

《商务智能与数据挖掘-谢邦昌》第一章读书笔记

 1.绪论 商务智能的含义就是指通过企业所拥有的数据和数据仓库的汇总,结合联机分析及数据挖掘技术挖掘出潜藏在数据库中的有用信息,并将其提供给决策者或部门主管作为平时运营的决策依据。而当企业面临危机时或必须立即做出重大决策时,也能依据数据仓库所提供的正确数据及时作出正确的决策。协助企业顺利解决问题。化危机为转机。更可见商务智能的重要性。 商务智能应用的几个方面 对于一般企业来说,商务智能主要应用在以下几个方面。1.了解运营状况,2.衡量绩效。3.改善关系。4.创造获利机会。 企业引用商务智能的流程 商务智能的核心:根据企业数据库整合成可以作为分析用的数据仓库。再进一步通过分析技术来探索数据。 《Building the Data Warehouse》的作者William Inmon认为数据仓库必须具有面对主题,整合性,时间转化,不易变化四个特性。 联机分析简单来说就是能让用户根据本身决策需求来浏览数据。动态且实时的产生其所需的报表,以提高分析效率的技术。事实上,他除了能提供在线实时数据分析模块外,更重要的是能展示多维度的数据。 商务智能的另一项重要技术:数据挖掘:是指在大量数据库中寻找有意义或是有价值的信息的过程。通过机器学习技术或是统计分析方法论。根据整合的数据加以分析探索,发掘出隐含在数据中的特性。通过专业领域知识整合及分析。从中找出合理且有用的信息,经过相关部门针对该模型的评估后,再提供给相关决策单位加以运用。 企业间的竞争模式,从传统的“红海策略”,即采取压低成本与价格的杀价流血竞争。到近来倡导以创新为核心竞争力的“蓝海策略”,不论哪一种策略模式,都是不断地从研发,制造,营销,客服或资源配置等运营的相关问题上。寻求问题的发生原因,并尝试找出解决方案,而运营阶段中,陆续积累的庞大数据,往往就是答案的隐身之处。这也是数据挖掘的目的。 数据库仓库强大而实用,但有一个局限性。就是他实质上反映的过去的历史,由于数据仓库经常在特定周期或时间点进行加载和处理。因此他只是表示一个时间点上的快照。即使构建了实时或是近似实时的数据仓库,其数据仍然只表示当前和历史的数据。无法达到预测的需要。与传统的统计分析方法不同的是,数据挖掘不是让人提出假设。然后据此去找相关数据。而是让数据仓库确定数据相关性。并允许采用与以往不同的模式对数据进行分析。

2012-09-19 · 1 min · bystander