C#版简易RSS阅读器。由VB版修改完成,感谢aowind的技术支持! 源代码: using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.Xml; using System.IO; using System.Threading; namespace YuLRSSReader { /// <summary> /// Form1 的摘要说明。 /// </summary> public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label3; private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.Button button1; private System.Windows.Forms.Label BlogName; private System.Windows.Forms.Label BlogDescription; private System.Windows.Forms.ListBox listBox1; private System.Windows.Forms.StatusBar statusBar1; private AxSHDocVw.AxWebBrowser axWebBrowser1; /// <summary> /// 必需的设计器变量。 /// </summary> private System.ComponentModel.Container components = null; public Form1() { // // Windows 窗体设计器支持所必需的 // InitializeComponent(); // // TODO: 在 InitializeComponent 调用后添加任何构造函数代码 // } /// <summary> /// 清理所有正在使用的资源。 /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows 窗体设计器生成的代码 /// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器修改 /// 此方法的内容。 /// </summary> private void InitializeComponent() { System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1)); this.label1 = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); this.textBox1 = new System.Windows.Forms.TextBox(); this.button1 = new System.Windows.Forms.Button(); this.BlogName = new System.Windows.Forms.Label(); this.BlogDescription = new System.Windows.Forms.Label(); this.listBox1 = new System.Windows.Forms.ListBox(); this.statusBar1 = new System.Windows.Forms.StatusBar(); this.axWebBrowser1 = new AxSHDocVw.AxWebBrowser(); ((System.ComponentModel.ISupportInitialize)(this.axWebBrowser1)).BeginInit(); this.SuspendLayout(); // // label1 // this.label1.Location = new System.Drawing.Point(8, 8); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(64, 23); this.label1.TabIndex = 0; this.label1.Text = "RSS地址:"; // // label2 // this.label2.Location = new System.Drawing.Point(8, 40); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(64, 23); this.label2.TabIndex = 1; this.label2.Text = "BLOG:"; // // label3 // this.label3.Location = new System.Drawing.Point(8, 72); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(64, 23); this.label3.TabIndex = 2; this.label3.Text = "描述:"; // // textBox1 // this.textBox1.Location = new System.Drawing.Point(72, 8); this.textBox1.Name = "textBox1"; this.textBox1.Size = new System.Drawing.Size(392, 21); this.textBox1.TabIndex = 3; this.textBox1.Text = ""; // // button1 // this.button1.Location = new System.Drawing.Point(472, 16); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(80, 64); this.button1.TabIndex = 4; this.button1.Text = "读取"; this.button1.Click += new System.EventHandler(this.button1_Click); // // BlogName // this.BlogName.Location = new System.Drawing.Point(72, 40); this.BlogName.Name = "BlogName"; this.BlogName.Size = new System.Drawing.Size(392, 23); this.BlogName.TabIndex = 5; // // BlogDescription // this.BlogDescription.Location = new System.Drawing.Point(72, 72); this.BlogDescription.Name = "BlogDescription"; this.BlogDescription.Size = new System.Drawing.Size(392, 23); this.BlogDescription.TabIndex = 6; // // listBox1 // this.listBox1.ItemHeight = 12; this.listBox1.Location = new System.Drawing.Point(0, 104); this.listBox1.Name = "listBox1"; this.listBox1.Size = new System.Drawing.Size(560, 112); this.listBox1.TabIndex = 7; this.listBox1.SelectedIndexChanged += new System.EventHandler(this.listBox1_SelectedIndexChanged); // // statusBar1 // this.statusBar1.Location = new System.Drawing.Point(0, 591); this.statusBar1.Name = "statusBar1"; this.statusBar1.Size = new System.Drawing.Size(562, 22); this.statusBar1.TabIndex = 8; // // axWebBrowser1 // this.axWebBrowser1.Dock = System.Windows.Forms.DockStyle.Bottom; this.axWebBrowser1.Enabled = true; this.axWebBrowser1.Location = new System.Drawing.Point(0, 223); this.axWebBrowser1.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("axWebBrowser1.OcxState"))); this.axWebBrowser1.Size = new System.Drawing.Size(562, 368); this.axWebBrowser1.TabIndex = 9; // // Form1 // this.AutoScaleBaseSize = new System.Drawing.Size(6, 14); this.ClientSize = new System.Drawing.Size(562, 613); this.Controls.Add(this.axWebBrowser1); this.Controls.Add(this.statusBar1); this.Controls.Add(this.listBox1); this.Controls.Add(this.BlogDescription); this.Controls.Add(this.BlogName); this.Controls.Add(this.button1); this.Controls.Add(this.textBox1); this.Controls.Add(this.label3); this.Controls.Add(this.label2); this.Controls.Add(this.label1); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.Name = "Form1"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "YuL\‘s RSS Reader"; this.Load += new System.EventHandler(this.Form1_Load); ((System.ComponentModel.ISupportInitialize)(this.axWebBrowser1)).EndInit(); this.ResumeLayout(false); } #endregion /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main() { Application.Run(new Form1()); } private void Form1_Load(object sender, System.EventArgs e) { this.axWebBrowser1.Width = this.Width; this.statusBar1.Text = "就绪"; } private Thread thread; private string fileFullPath = Application.StartupPath + "~tempdoc.xml"; private void LoadRss() { this.statusBar1.Text = "正在读取" + this.textBox1.Text + "并校验…"; this.LoadXml2Coach(this.textBox1.Text); this.statusBar1.Text = "正在读取BLOG相关信息…"; this.LoadTitle(); this.statusBar1.Text = "正在读取RSS内容信息…"; this.LoadItem(); this.statusBar1.Text = "完成"; } private void LoadXml2Coach(String url) { XmlDocument doc = new XmlDocument(); doc.Load(url); doc.Save(this.fileFullPath); } private void LoadTitle() { XmlDocument doc = new XmlDocument(); doc.Load(this.fileFullPath); XmlNodeList nodeList; nodeList = doc.SelectNodes("/rss/channel"); this.BlogName.Text = nodeList[0].SelectSingleNode("title").InnerText; this.BlogDescription.Text = nodeList[0].SelectSingleNode("description").InnerText; } private void LoadItem() { XmlDocument doc = new XmlDocument(); doc.Load(this.fileFullPath); XmlNodeList nodeList; nodeList = doc.SelectNodes("/rss/channel/item"); this.listBox1.Items.Clear(); XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable); ns.AddNamespace("dc","http://purl.org/dc/elements/1.1/"); try { for(int i = 0; i < nodeList.Count; i++) { this.listBox1.Items.Add("[" + nodeList[i].SelectSingleNode("dc:creator",ns).InnerText + "]" + nodeList[i].SelectSingleNode("title").InnerText); } } catch(Exception ex) { MessageBox.Show(ex.ToString()); } } private void LoadHtml() { XmlDocument doc = new XmlDocument(); doc.Load(this.fileFullPath); XmlNodeList nodeList; nodeList = doc.SelectNodes("/rss/channel/item"); bool flag; string temp = ""; string content = ""; this.statusBar1.Text = "正在读取文章内容…"; XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable); ns.AddNamespace("dc","http://purl.org/dc/elements/1.1/"); for(int i = 0; i < nodeList.Count; i++) { temp = "[" + nodeList[i].SelectSingleNode("dc:creator",ns).InnerText + "]" + nodeList[i].SelectSingleNode("title").InnerText; if(this.listBox1.SelectedItem.ToString().Equals(temp)) { content = content + "<html><head><meta http-equiv=‘content-type‘ content=‘text/html;charset=UTF-8‘></head><body>"; content = content + "<table width=‘100%‘ height=‘80‘ bgcolor=‘#eeeeee‘><tr><td><b>标题:</b><a href=‘"; content = content + nodeList[i].SelectSingleNode("link").InnerText; content = content + "‘ target=‘_blank‘>"; content = content + nodeList[i].SelectSingleNode("title").InnerText; content = content + "</a><br><b>作者:</b>"; content = content + nodeList[i].SelectSingleNode("dc:creator",ns).InnerText; content = content + "</tb></tr></table>"; content = content + nodeList[i].SelectSingleNode("description").InnerText; content = content + "</body></html>"; flag = SaveTextFile(Application.StartupPath + "~temp.html", content); object flags = 0; object targetFrame = String.Empty; object postData = String.Empty; object headers = String.Empty; this.axWebBrowser1.Navigate(Application.StartupPath + "~temp.html", ref flags, ref targetFrame, ref postData, ref headers); break; } } this.statusBar1.Text = "完成"; } private bool SaveTextFile(string filePath, string fileContent) { System.IO.StreamWriter sw = null; try { sw = new StreamWriter(filePath,false); sw.Write(fileContent); return true; } catch(Exception ex) { MessageBox.Show(ex.ToString()); return false; } finally { if(sw != null) sw.Close(); } } private void button1_Click(object sender, System.EventArgs e) { try { this.thread = new Thread(new ThreadStart(this.LoadRss)); this.thread.Start(); } catch(Exception ex) { MessageBox.Show(ex.ToString()); } } private void listBox1_SelectedIndexChanged(object sender, System.EventArgs e) { try { this.thread = new Thread(new ThreadStart(this.LoadHtml)); this.thread.Start(); } catch(Exception ex) { MessageBox.Show(ex.ToString()); } } } }
C#实现断点续传详细剖析
· 摘要:这里介绍C#实现断点续传,在了解HTTP断点续传的原理之前,让我们先来了解一下HTTP协议,HTTP协议是一种基于tcp的简单协议,分为请求和回复两种。 · C#语言还是比较常见的东西,这里我们主要介绍C#实现断点续传,包括介绍HTTP协议是一种基于tcp的简单协议等方面。 在了解HTTP断点续传的原理之前,让我们先来了解一下HTTP协议,HTTP协议是一种基于tcp的简单协议,分为请求和回复两种。请求协议是由客户机(浏览器)向服务器(WEB SERVER)提交请求时发送报文的协议。回复协议是由服务器(web server),向客户机(浏览器)回复报文时的协议。请求和回复协议都由头和体组成。头和体之间以一行空行为分隔。 以下是一个请求报文与相应的回复报文的例子: 1. GET /image/index_r4_c1.jpg HTTP/1.1 2. Accept: */* 3. Referer: http://192.168.3.120:8080 4. Accept-Language: zh-cn 5. Accept-Encoding: gzip, deflate 6. User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.0.3705) 7. Host: 192.168.3.120:8080 8. Connection: Keep-Alive 9. 10. HTTP/1.1 200 OK 11. Server: Microsoft-IIS/5.0 12. Date: Tue, 24 Jun 2003 05:39:40 GMT 13. Content-Type: image/jpeg 14. Accept-Ranges: bytes 15. Last-Modified: Thu, 23 May 2002 03:05:40 GMT 16. ETag: "bec48eb862c21:934" 17. Content-Length: 2827 下面我们就来说说C#实现断点续传,顾名思义,断点续传就是在上一次下载时断开的位置开始继续下载。 在HTTP协议中,可以在请求报文头中加入Range段,来表示客户机希望从何处继续下载。 比如说从第1024字节开始下载,请求报文如下: 1. GET /image/index_r4_c1.jpg HTTP/1.1 2. Accept: */* 3. Referer: http://192.168.3.120:8080 4. Accept-Language: zh-cn 5. Accept-Encoding: gzip, deflate 6. User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.0.3705) 7. Host: 192.168.3.120:8080 8. Range:bytes=1024- 9. Connection: Keep-Alive .NET中的相关类,明白了上面的原理,那么,我们来看看.NET FRAMEWORK中为我们提供了哪些类可以来做这些事。完成HTTP请求System.Net.HttpWebRequest HttpWebRequest 类对 WebRequest 中定义的属性和方法提供支持,也对使用户能够直接与使用 HTTP 的服务器交互的附加属性和方法提供支持。 HttpWebRequest 将发送到 Internet 资源的公共 HTTP 标头值公开为属性,由方法或系统设置。下表包含完整列表。可以将 Headers 属性中的其他标头设置为名称/值对。但是注意,某些公共标头被视为受限制的,它们或者直接由 API公开,或者受到系统保护,不能被更改。Range也属于被保护之列,不过,.NET为开发者提供了更方便的操作,就是 AddRange方法,向请求添加从请求数据的开始处或结束处的特定范围的字节范围标头,以上介绍C#实现断点续传。
C#制作新闻阅读器
一、弄清结构再动手 要想轻松的抽取RSS信息,自然先要了解它的结构,所谓“知己知彼,百战不殆”嘛。 1、RSS的结构 我们先打开百度新闻一个RSS链接,如果你再多打开几个别的网站的RSS链接,会发现他们都有大致相同的结构。而我们在揭秘RSS(上)中为大家讲解的其实就是编成实现这样的一个XML文件。 为了能够方便地对这样的XML文档进行处理,在本文里,我们使用C#作为开发的语言。 分析整个RSS链接后,我们知道RSS大致的结构入图1。 2、抽取的原理 知道了结构,我们还要知道结构中各部分的含义。在图1中RSS节点表示当前是一个RSS文件,它由一个CHANNEL节点及其子节点组成,其中一些子节点提供关于频道本身的信息,比如title表示频道的名称(“百度互联网新闻”)。 CHANNEL节点又包含多个ITEM子节点,而ITEM节点就是程序需要处理的部分,因为它对应着每条实际的新闻项信息, 每个ITEM节点又通过其子节点提供关于这条新闻的详细信息,比如title表示新闻的标题(“微软IM称王”),link对应新闻实际的链接。 RSS具体规范可查看http://blogs.law.harvard.edu/tech/rss 知道了这些后,要编程就不困难啦。我们只需提取并显示出CHANNEL和ITEM下的各条信息就可以了。现在来看看具体的实现方法吧。 二.做个程序读新闻 对RSS有一定了解后,我们开始编写程序。先还是需要一个最简单的界面。新建一个Win Form 工程,在Form上放置一个Label,一个文本框txtURL用来输入RSS链接(就是各网站RSS链接中包含的地址),一个按钮bnRead用来执行读取新闻, 一个TreeView树形控件treeRSS显示读出的新闻项。 1、定义装载结构 根据上面分析的RSS结构,我们首先来建立一个rss类,用它来装载RSS链接中CHANNEL和ITEM的各条信息。代码如下: public class rss { public struct Channel { public string Title; public Hashtable Items; } public struct Item { public string Title; public string Description; public string Link; } } Channel结构将存储CHANNEL节点包含的所有子节点信息,其中Items成员字段是一个Hashtable集合,程序会将Item结构作为对象加入集合,用来存储Channel下的所有Item节点。这里我只读取了有限的几个节点,读者可以根据实际需要扩展整个结构定义。 2、从RSS链接中获取新闻信息 现在我们就可以开始编写读取函数,将抽取出的RSS信息放入上面设计好的结构中。 C#提供了专门的类来访问XML, 使我们能够轻松地读出RSS的内容。代码如下: XmlTextReader Reader = new XmlTextReader(URL); XmlValidatingReader Valid = new XmlValidatingReader(Reader); Valid.ValidationType = ValidationType.None; XmlDocument xmlDoc= new XmlDocument(); xmlDoc.Load(Reader); 使用XmlDocument类将txtURL中输入的RSS链接加载后,首先通过FoundChildNode函数,找到Channel节点。 private XmlNode FoundChildNode(XmlNode Node,string Name) { XmlNode childlNode = null; for (int i=0;i < Node.ChildNodes.Count;i++) { if ( Node.ChildNodes[i].Name == Name && Node.ChildNodes[i].ChildNodes.Count > 0 ) { childlNode = Node.ChildNodes[i]; return childlNode; } } return childlNode; } XmlNode rssNode = FoundChildNode(xmlDoc,"rss"); XmlNode channelNode = FoundChildNode(rssNode,"channel"); 然后我们就可以遍历它的子节点,根据子节点的Name属性,读取我们需要的信息。 rss.Channel channel=new rss.Channel(); channel.Items=new Hashtable(); { switch ( channelNode.ChildNodes[i].Name ) { case "title": { channel.Title = channelNode.ChildNodes[i].InnerText; break; } case "item": { rss.Item item=this.getRssItem(channelNode.ChildNodes[i]); channel.Items.Add(channel.Items.Count,item ); break; } } } 如果发现是item子节点,就调用getRssItem函数,同样通过遍历子节点的方法,将其子节点内容填入Item结构中,然后再添加到Channel结构的Items集合中。因为本程序并不关心添加到集合的键值,只需要它是不重复的值,所以我传入了Count属性。 3.将读出的信息显示在程序中 将RSS内容读出后,就需要把信息展示给用户了。我们这里用的是基本的TreeView方法,通过遍历Channel结构的Items集合,将其标题添加到TreeView中。 private void ViewRss(rss.Channel channel) { treeRss.BeginUpdate(); treeRss.Nodes.Clear(); TreeNode channelNode=treeRss.Nodes.Add(channel.Title ); channelNode.Tag=""; for (int i=0;i <channel.Items.Count ;i++) { rss.Item item=(rss.Item)channel.Items[i]; TreeNode itemNode=channelNode.Nodes.Add(item.Title ); itemNode.Tag=item.Link; } treeRss.ExpandAll(); treeRss.EndUpdate(); } 同时我们还可以设置TreeView的每个子节点的Tag属性为它对应的链接。以便当选中子节点时就可以通过读取Tag属性访问具体的信息。 private void treeRss_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e) { TreeNode itemNode=e.Node ; string URL=itemNode.Tag.ToString(); if (URL.Length!=0) System.Diagnostics.Process.Start( URL); } 程序运行效果如图2。 三.小结 怎么样,一个简单的RSS新闻阅读器就按前面所说轻松完成了,容易吧。虽然它还有很多不足,但如果大家通过这个例子学会了抽取RSS链接信息的基本方法,那就足够了!
C#制作源阅读器
1 需求分析 这是一个rss源阅读器,能够读取xml文件以实现链接网页的目的。其主要功能是通过添加url来获取种子并阅读网页,使得浏览网页更加轻松,项目中主要包含了增加、删除、修改频道的功能。其界面如下: 2 概要设计 设计思路:主窗体中分为节点跟内容显示两个窗口(即左边为节点,右边为文章详细内容),并从主窗体的.cs文件中连接到add.cs跟del.cs窗口以实现整个RSS阅读器的完整功能(即包括增删改节点的功能)。 关键点:如何将种子读取并加载上去、如何下载下载.xml文档并解析种子、如何实现多线程任务管理、如何将添加的频道添加到txt文档中并在主窗口显示、如何修改和删除节点。 框架设计: 主要类设计: 1、在读取文章模块: Article.cs类中:有title跟url的封装属性,用来体现文章的标题跟url路径。 RssFeed.cs类是初始化了title、url跟destination,到网上下载rss源的种子文档,并解析了已有的.xml文件,以此来获取每个节点。 FeedManager.cs类是读取feeds.txt种子文件并加载文件信息使其显示在webBrowser中 Form1.cs中实现了多线程任务管理,也将feedList中种子信息传到设计窗口显示出来。 2、增加频道模块: 添加了一个add.cs窗口,在此窗口中实现了添加文章的title、url跟destination三项并将之保存到feeds.txt文档中。 3、删除/修改频道模块: 添加了一个del.cs窗口,在此窗口中用了一个richTextBox来显示打开后的feeds.txt文档的内容,并在其中进行文档的编辑(即修改或删除节点),并用按钮进行保存。 3 知识点解析 1、封装一个文件: public string Title { get { return title; } set { title = value; } } 2、加载信息:(读取种子文件并将文件加载到feedList中去) string filepath = path + "\\feeds.txt"; StreamReader sr = new StreamReader(filepath,Encoding.Default); string line = ""; while ((line = sr.ReadLine()) != null) { RssFeed rf = new RssFeed(); rf.FeedName = line; rf.Url = sr.ReadLine(); rf.Description = sr.ReadLine(); FeedList.Add(rf); } 3、网上下载rss种子文件并解析xml文件 WebClient wc = new WebClient(); wc.DownloadFile(this.url, "temp.xml"); XmlDocument myXml = new XmlDocument(); myXml.Load("temp.xml"); XmlNode root = myXml.DocumentElement; XmlNode channel = root.ChildNodes[0]; 4、获取节点(先判断是否存在节点) if (node.Name.Equals("item")) { Article a = new Article(); a.Title = node.ChildNodes[0].InnerText; a.Url = node.ChildNodes[1].InnerText; Articles.Add(a); } 5、读取种子并在主窗体添加节点 for (int i = 0; i < list.Count; ++i) { TreeNode feedNode = new TreeNode(list[i].FeedName); feedNode.Tag = list[i]; rootNode.Nodes.Add(feedNode); } tvFeeds.Nodes.Add(rootNode); 6、线程的管理: 启动线程,并将参数传递到线程入口函数: Thread thread = new Thread(new ParameterizedThreadStart(RunThread)); thread.Start(node); 事件的处理函数: TreeNode node = e.Node; this.BeginInvoke(uad, new object[] { node }); 7、添加频道的窗口中触发“添加”按钮的事件(将自己添加的title、url、destination添加到已有的feeds.txt文档中): string filepath = Application.StartupPath + "\\feeds.txt"; //FileStream fs = File.Open("feeds.txt", FileMode.Create, FileAccess.Write); StreamWriter sw = new StreamWriter(filepath,true, Encoding.GetEncoding("gb2312")); sw.WriteLine(textBox1.Text); sw.WriteLine(textBox2.Text); sw.WriteLine(textBox3.Text); sw.Close(); MessageBox.Show("添加成功!"); 8、用流和文件来读取文档并进行修改后保存操作: 打开feeds.txt文档并在richTextBox中显示文档内容(触发“打开”按钮事件): OpenFileDialog feeds = new OpenFileDialog(); if (feeds.ShowDialog(this) == System.Windows.Forms.DialogResult.OK) { string file = feeds.FileName; richTextBox1.Text = System.IO.File.ReadAllText(file, Encoding.Default); } 将richTextBox中修改过的文件覆盖保存到feeds.txt中,(“保存”按钮事件): richTextBox1.SaveFile(Application.StartupPath + "\\feeds.txt", RichTextBoxStreamType.PlainText);
原文地址:https://www.cnblogs.com/blogpro/p/11458422.html
时间: 2024-11-08 20:54:29