<?xml version="1.0" encoding="gb2312"?>
<rss version="2.0">
<channel>
<title><![CDATA[ftp搜索引擎的设计和实现]]></title>
        <image>
        <title>http://hi.baidu.com</title>
        <link>http://hi.baidu.com</link>
        <url>http://img.baidu.com/img/logo-hi.gif</url>
        </image>
<description><![CDATA[从设计到编码，一步一步打造一个完备的ftp搜索]]></description>
<link>http://hi.baidu.com/weichao%5Fzju</link>
<language>zh-cn</language>
<generator>www.baidu.com</generator>
<ttl>5</ttl>


<item>
        <title><![CDATA[浙江大学-飘渺水云间(俗称: 88) bbs精华区搜索]]></title>
        <link><![CDATA[http://hi.baidu.com/weichao%5Fzju/blog/item/18c7bb0af2cd5c1794ca6b1b.html]]></link>
        <description><![CDATA[
		
		&nbsp;&nbsp;&nbsp;    基于&ldquo;W-cyclone文件搜索引擎&rdquo;强力打造的飘渺水云间精华区搜索已经进入测试阶段，不久后将向所有在校同学开放。<br>
&nbsp;&nbsp;&nbsp;    此次打造的精华区搜索引擎跟FTP搜索有点区别，不仅可以搜文件名，还可以按作者搜索，或者两个一起作为条件。<br>
&nbsp;&nbsp;&nbsp;    经过此次的代码改写后，W-cyclone更加完善和通用！<br>
放几张截图：<br>
<br>
这是搜索框，类型那里可以选择文件、目录<br>
<div forimg="1"><img border="0" src="http://hiphotos.baidu.com/weichao%5Fzju/pic/item/e0cbb7505fad2f40843524e1.jpg" small="0" class="blogimg"><br>
<br>
搜索文件名，结果页面（logo还没换，还是用的softp的）：<br>
<div forimg="1">
<div forimg="1"><img border="0" src="http://hiphotos.baidu.com/weichao%5Fzju/pic/item/3ad44ed0594b95aca1ec9c3b.jpg" small="0" class="blogimg"></div>
</div>
<br>
<br>
搜索id，结果页面：<br>
<div forimg="1"><img border="0" src="http://hiphotos.baidu.com/weichao%5Fzju/pic/item/88b0814ba96489d283025ce9.jpg" small="0" class="blogimg"></div>
<br>
<br>
同时搜索文件名和id，结果页面：<br>
<div forimg="1">
<div forimg="1"><img border="0" src="http://hiphotos.baidu.com/weichao%5Fzju/pic/item/c9a1b422b24608d0d6cae23b.jpg" small="0" class="blogimg"></div>
</div>
</div> <a href="http://hi.baidu.com/weichao%5Fzju/blog/item/18c7bb0af2cd5c1794ca6b1b.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/weichao%5Fzju/blog/category/%C4%AC%C8%CF%B7%D6%C0%E0">默认分类</a>&nbsp;<a href="http://hi.baidu.com/weichao%5Fzju/blog/item/18c7bb0af2cd5c1794ca6b1b.html#comment">查看评论</a>]]></description>
        <pubDate>2009-04-19  21:12</pubDate>
        <category><![CDATA[默认分类]]></category>
        <author><![CDATA[weichao_zju]]></author>
		<guid>http://hi.baidu.com/weichao%5Fzju/blog/item/18c7bb0af2cd5c1794ca6b1b.html</guid>
</item>

<item>
        <title><![CDATA[浙江大学ftp搜索demo版 & 百度hi]]></title>
        <link><![CDATA[http://hi.baidu.com/weichao%5Fzju/blog/item/5500fbca111a574ef31fe7a9.html]]></link>
        <description><![CDATA[
		
		浙江大学ftp搜索demo版：<br>
<a href="http://weichao.3322.org/product/demo/ftpsearch/" target="_blank">http://weichao.3322.org/product/demo/ftpsearch/</a><br>
<br>
本人即日起继续ftp搜索以及文件搜索的研究，有兴趣的可以加我百度hi<br>
id是: <strong>weichao_zju</strong><br>
<font color="#ff0000">百度Hi 文件搜索引擎研究群</font>： 1181045<br>
<br>
预告一下，正在开发一个可以实时更新的文件搜索引擎，请关注！<br>
本博客不定期更新。 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/weichao%5Fzju/blog/category/ftp%CB%D1%CB%F7%D2%FD%C7%E6">ftp搜索引擎</a>&nbsp;<a href="http://hi.baidu.com/weichao%5Fzju/blog/item/5500fbca111a574ef31fe7a9.html#comment">查看评论</a>]]></description>
        <pubDate>2009-04-08  12:39</pubDate>
        <category><![CDATA[ftp搜索引擎]]></category>
        <author><![CDATA[weichao_zju]]></author>
		<guid>http://hi.baidu.com/weichao%5Fzju/blog/item/5500fbca111a574ef31fe7a9.html</guid>
</item>

<item>
        <title><![CDATA[ftp搜索引擎的设计和实现：5.1 CGI脚本（二）]]></title>
        <link><![CDATA[http://hi.baidu.com/weichao%5Fzju/blog/item/34d1634aa4257d2208f7ef12.html]]></link>
        <description><![CDATA[
		
		<p><font color="#ff0000" size="2">欢迎转载，但请注明出处，并给活力链接。谢谢</font></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 有表单的网页通常需要跟服务器交互，比如你要把输入的用户名、密码、生日等提交，以便服务器处理。cgi脚本怎样获取用户的输入？<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 为了传递一个参数给脚本，可以在URL中使用 (?) 插入脚本名词和参数之间。<br>
&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 表单从浏览器发给服务器有两种方法。GET 和 POST。 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GET方法将数据打包放置在环境变量QUERY_STRING中作为URL整体的一部分传递给服务器。 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; POST做很多类似GET同样的事情, 不同的地方就是它是分离地传递数据给脚本. 你的脚本通过标准输入获取这些数据. (有些Web服务器是存储在临时文件中.) 这个QUERY_STRING环境变量将不再设置。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 那你用那个方法呢? POST是个安全的方法, 尤其如果你的表单中有很多数据的话. 当你用GET, 这个服务器就分配变量QUERY_STRING给所有的表单数据, 但是这个变量可存储量是有限的. 换句话说，如果你有很多数据但是你又用GET，你会丢失很多数据. <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果你用POST, 你可以尽可能多地使用数据, 因为这些数据从来也不分配到一个变量里. </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; URL编码是一种浏览器用来打包表单输入的格式. 浏览器从表单中获取所有的name和其中的值 ，将他们作为name/value参数编码, 移去那些不能传送的字符, 将数据排行等等，这些还取决于你用GET还是POST?作为URL的一部分或者分离地发给服务器. 不管哪种情况, 在服务器端的表单输入格式样子象这样: <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; theName=Ichabod+Crane&amp;gender=male&amp;status=missing&amp;headless=yes</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; URL编码遵循下列规则: <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 每对name/value由&amp;符分开. <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 每对来自表单的name/value由=符分开. 如果用户没有输入值给这个name,那么这个name还是出现，只是无值(象这样 "name="). <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 任何特殊的字符(就是那些不是简单的七位ASCII，如汉字) 将以百分符%用十六进制编码. 当然也包括象 =, &amp;, 和 % 这些特殊的字符. <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在输入区中的空格将以加号+显示. </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 因为表单输入是用这个URL编码传递给你的脚本的，在你用这些参数之前必须解码。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 看看这个url：<br>
<a href="http://iseftp.2288.org:52080/cgi-bin/snapshot?url=0day.happy98.org/">http://iseftp.2288.org:52080/cgi-bin/snapshot?url=0day.happy98.org/</a></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 它指示脚本名称为snapshot，第一个变量是url，值为0day.happy98.org/</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看src/search/queryentry.cpp里的getQueryCondition()函数，该函数用于search程序解析浏览器的输入。<br>
</p> <a href="http://hi.baidu.com/weichao%5Fzju/blog/item/34d1634aa4257d2208f7ef12.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/weichao%5Fzju/blog/category/ftp%CB%D1%CB%F7%D2%FD%C7%E6">ftp搜索引擎</a>&nbsp;<a href="http://hi.baidu.com/weichao%5Fzju/blog/item/34d1634aa4257d2208f7ef12.html#comment">查看评论</a>]]></description>
        <pubDate>2007-04-06  20:57</pubDate>
        <category><![CDATA[ftp搜索引擎]]></category>
        <author><![CDATA[weichao_zju]]></author>
		<guid>http://hi.baidu.com/weichao%5Fzju/blog/item/34d1634aa4257d2208f7ef12.html</guid>
</item>

<item>
        <title><![CDATA[ftp搜索引擎的设计和实现：5.1 CGI脚本（一）]]></title>
        <link><![CDATA[http://hi.baidu.com/weichao%5Fzju/blog/item/f630553142448418eac4af62.html]]></link>
        <description><![CDATA[
		
		<p><font color="#ff0000" size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 欢迎转载，但请注明出处，并给活力链接。谢谢</font></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这一部分首先来介绍一下什么是cgi脚本。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CGI 意思为 Common Gateway Interface, 一种基于浏览器的输入、在Web服务器上运行的程序方法. CGI脚本 使你的浏览器与用户能交互，为了在数据库中寻找一个名词, 提供你写入的评论，或者从一个表单中选择几个条目并且能得到一个明确的回答. 如果你曾经遇到过在web上填表或进行搜索, 你就是用的CGI脚本. 你那时也许没有意识到，因为大部分工作是在服务器上运行的，你看到的只是结果.<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CGI脚本简单地讲是个运行在Web服务器上的程序, 由浏览器的输入触发。这个脚本通常象服务器和系统中其他程序如数据库的桥梁。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CGI 脚本难道不是一个真正的脚本?按照你的服务器的支持, 他们可能是一个编译好的程序或者批命令文件或者其他可执行的东西。为了简单起见，我们统称他们为脚本scripts. <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CGI脚本是用下列两种方法使用的: 作为一个表单的ACTION 或 作为一个页中的直接link。一个URL指向一个CGI脚本。一个CGI脚本的URL能如普通的URL一样在任何地方出现。 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一个CGI脚本的通常流程是：<br>
1. 服务器接收请求, 按照那个URL指向的脚本文件(注意文件的位置和扩展名),执行脚本。<br>
2. 脚本执行基于输入数据的操作，包括查询数据库、计算数值或调用系统中其他程序. <br>
3. 脚本产生某种Web服务器能理解的输出结果. <br>
4. 服务器接收来自脚本的输出并且把它传回浏览器，让用户了解结果。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下面来解析一个cgi脚本的实现：<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 首先一个cgi脚本都有一个输出头部，这个头部实际不是文本的一部分，是服务器与浏览器之间的信息协议，你实际看不到。 <br>
有三个类型的头部: Content-type, Location, 和Status. Content-type 最普遍。有关content-type解释可以见有关HTML的说明, 一个你可以发出的特定编码象这样： <br>
Content-type: text/html<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在这个例子中，输出数据的类型是text/html; 换句话说, 他是个HTML文件. </p>
<p>通用格式和content-types.&nbsp;&nbsp;&nbsp;<br>
<table cellpadding="0" border="1">
<tbody>
    <tr>
        <td style="BORDER-RIGHT: #d4d0c8; PADDING-RIGHT: 0.75pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 0.75pt; PADDING-BOTTOM: 0.75pt; BORDER-LEFT: #d4d0c8; PADDING-TOP: 0.75pt; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent">
<p style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 24pt"><span style="FONT-SIZE: 12pt">Format</span></p>
</td>
        <td style="BORDER-RIGHT: #d4d0c8; PADDING-RIGHT: 0.75pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 0.75pt; PADDING-BOTTOM: 0.75pt; BORDER-LEFT: #d4d0c8; PADDING-TOP: 0.75pt; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent">
<p style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 24pt"><span style="FONT-SIZE: 12pt">Content-Type</span></p>
</td>
    </tr>
    <tr>
        <td style="BORDER-RIGHT: #d4d0c8; PADDING-RIGHT: 0.75pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 0.75pt; PADDING-BOTTOM: 0.75pt; BORDER-LEFT: #d4d0c8; PADDING-TOP: 0.75pt; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent">
<p style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 24pt"><span style="FONT-SIZE: 12pt">HTML</span></p>
</td>
        <td style="BORDER-RIGHT: #d4d0c8; PADDING-RIGHT: 0.75pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 0.75pt; PADDING-BOTTOM: 0.75pt; BORDER-LEFT: #d4d0c8; PADDING-TOP: 0.75pt; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent">
<p style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 24pt"><span style="FONT-SIZE: 12pt">text/html</span></p>
</td>
    </tr>
    <tr>
        <td style="BORDER-RIGHT: #d4d0c8; PADDING-RIGHT: 0.75pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 0.75pt; PADDING-BOTTOM: 0.75pt; BORDER-LEFT: #d4d0c8; PADDING-TOP: 0.75pt; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent">
<p style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 24pt"><span style="FONT-SIZE: 12pt">Text</span></p>
</td>
        <td style="BORDER-RIGHT: #d4d0c8; PADDING-RIGHT: 0.75pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 0.75pt; PADDING-BOTTOM: 0.75pt; BORDER-LEFT: #d4d0c8; PADDING-TOP: 0.75pt; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent">
<p style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 24pt"><span style="FONT-SIZE: 12pt">text/plain</span></p>
</td>
    </tr>
    <tr>
        <td style="BORDER-RIGHT: #d4d0c8; PADDING-RIGHT: 0.75pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 0.75pt; PADDING-BOTTOM: 0.75pt; BORDER-LEFT: #d4d0c8; PADDING-TOP: 0.75pt; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent">
<p style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 24pt"><span style="FONT-SIZE: 12pt">GIF</span></p>
</td>
        <td style="BORDER-RIGHT: #d4d0c8; PADDING-RIGHT: 0.75pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 0.75pt; PADDING-BOTTOM: 0.75pt; BORDER-LEFT: #d4d0c8; PADDING-TOP: 0.75pt; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent">
<p style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 24pt"><span style="FONT-SIZE: 12pt">image/gif</span></p>
</td>
    </tr>
    <tr>
        <td style="BORDER-RIGHT: #d4d0c8; PADDING-RIGHT: 0.75pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 0.75pt; PADDING-BOTTOM: 0.75pt; BORDER-LEFT: #d4d0c8; PADDING-TOP: 0.75pt; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent">
<p style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 24pt"><span style="FONT-SIZE: 12pt">JPEG</span></p>
</td>
        <td style="BORDER-RIGHT: #d4d0c8; PADDING-RIGHT: 0.75pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 0.75pt; PADDING-BOTTOM: 0.75pt; BORDER-LEFT: #d4d0c8; PADDING-TOP: 0.75pt; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent">
<p style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 24pt"><span style="FONT-SIZE: 12pt">image/jpeg</span></p>
</td>
    </tr>
    <tr>
        <td style="BORDER-RIGHT: #d4d0c8; PADDING-RIGHT: 0.75pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 0.75pt; PADDING-BOTTOM: 0.75pt; BORDER-LEFT: #d4d0c8; PADDING-TOP: 0.75pt; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent">
<p style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 24pt"><span style="FONT-SIZE: 12pt">PostScript</span></p>
</td>
        <td style="BORDER-RIGHT: #d4d0c8; PADDING-RIGHT: 0.75pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 0.75pt; PADDING-BOTTOM: 0.75pt; BORDER-LEFT: #d4d0c8; PADDING-TOP: 0.75pt; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent">
<p style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 24pt"><span style="FONT-SIZE: 12pt">Application/postscript</span></p>
</td>
    </tr>
    <tr>
        <td style="BORDER-RIGHT: #d4d0c8; PADDING-RIGHT: 0.75pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 0.75pt; PADDING-BOTTOM: 0.75pt; BORDER-LEFT: #d4d0c8; PADDING-TOP: 0.75pt; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent">
<p style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 24pt"><span style="FONT-SIZE: 12pt">MPEG</span></p>
</td>
        <td style="BORDER-RIGHT: #d4d0c8; PADDING-RIGHT: 0.75pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 0.75pt; PADDING-BOTTOM: 0.75pt; BORDER-LEFT: #d4d0c8; PADDING-TOP: 0.75pt; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent">
<p style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 24pt"><span style="FONT-SIZE: 12pt">video/mpeg</span></p>
</td>
    </tr>
</tbody>
</table>
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 注意content-type 后面必须跟一个空行. 如果你没有空行，服务器将无法搞清这个头部在哪里结束。 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果你的cgi脚本是C语言写的，通常是这样开头的：<br>
<font color="#0000ff">printf("Content-type:text/html\n\n");</font></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果是个bash shell，则开头是：<br>
<font color="#0000ff">#!/bin/sh<br>
echo Content-type: text/plain<br>
echo</font></p>
<p><br>
<strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 输出数据</strong><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 你输出的数据应该符合你所规定的content-type; 如果content-type是text/html, 输出应该是HTML代码. 如果content-type是image/gif, 输出应该是在一个二进制的GIF文件. </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一个最简单的cgi脚本例子：<br>
<font color="#0000ff">#!/bin/sh<br>
echo Content-type: text/plain<br>
echo<br>
/bin/date</font></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 把该脚本命名为getdate，放在web服务器的cgi-bin目录。假设web服务器的域名是weichao.3322.org，当你在浏览器中输入<br>
<a href="http://weichao.3322.org/cgi-bin/getdate">http://weichao.3322.org/cgi-bin/getdate</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 你在浏览器里得到类似下面的输出：<br>
<font color="#008080">Wed Apr&nbsp;&nbsp;&nbsp;&nbsp; 4 22:33:31 CST 2007</font></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下节来介绍怎么跟cgi脚本交互。<br>
</p> <a href="http://hi.baidu.com/weichao%5Fzju/blog/item/f630553142448418eac4af62.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/weichao%5Fzju/blog/category/ftp%CB%D1%CB%F7%D2%FD%C7%E6">ftp搜索引擎</a>&nbsp;<a href="http://hi.baidu.com/weichao%5Fzju/blog/item/f630553142448418eac4af62.html#comment">查看评论</a>]]></description>
        <pubDate>2007-04-04  23:04</pubDate>
        <category><![CDATA[ftp搜索引擎]]></category>
        <author><![CDATA[weichao_zju]]></author>
		<guid>http://hi.baidu.com/weichao%5Fzju/blog/item/f630553142448418eac4af62.html</guid>
</item>

<item>
        <title><![CDATA[ftp搜索引擎的设计和实现：4.9 建立倒排索引模块代码结构]]></title>
        <link><![CDATA[http://hi.baidu.com/weichao%5Fzju/blog/item/d9f935d8bc21833432fa1c77.html]]></link>
        <description><![CDATA[
		
		<p><font color="#ff0000" size="2">欢迎转载，但请注明出处，并给活力链接。谢谢</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在这一部分的最后一节，来介绍一下W-cyclone ftp搜索引擎的“建立倒排索引模块”的代码结构。<br>
该模块的代码包括以下文件：</font></p>
<p><font size="2"><br>
&nbsp;&nbsp;&nbsp;&nbsp; buildindex.cpp：包含该模块的main函数，首先fork出两个子进程，一个子进程负责按顺序扫描attr文件；另一个子进程负责扫描path文件。等到两个子进程成功退出后，计算各个文件夹的大小。</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;&nbsp; calcdirsize.cpp：计算各个文件夹大小的类的实现。（参见4.6节）</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;&nbsp; fileinforindex.cpp：负责扫描attr文件的类的实现。按顺序逐行扫描各attr文件，每一行对应生成一个Fileinformation结构，以二进制写入到inforindex文件中。</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;&nbsp; filenameindex.cpp：负责扫描path文件的类的实现。按顺序逐一扫描path文件，生成双字母倒排索引，写入到对应的索引文件中。</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;&nbsp; 需要说明的是，按上文介绍的双字母倒排来建立索引，程序并不支持插入、更新和删除索引。要想更新索引，只有重建所有索引。好在该搜索引擎是用于搜索文件名的ftp搜索引擎，索引的大小以及建索引的时间在可以接受的范围之内。</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;&nbsp; 最后介绍一个脚本dir.sh。该脚本用于在一个指定目录内生成256个文件夹，文件夹名为0-255.或者在一个指定目录内删除文件夹名为0-255的所有目录。也许你已经想到了，它用于在重建索引时删除整个索引目录和创建整个索引目录。<br>
</font></p> <a href="http://hi.baidu.com/weichao%5Fzju/blog/item/d9f935d8bc21833432fa1c77.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/weichao%5Fzju/blog/category/ftp%CB%D1%CB%F7%D2%FD%C7%E6">ftp搜索引擎</a>&nbsp;<a href="http://hi.baidu.com/weichao%5Fzju/blog/item/d9f935d8bc21833432fa1c77.html#comment">查看评论</a>]]></description>
        <pubDate>2007-04-02  20:29</pubDate>
        <category><![CDATA[ftp搜索引擎]]></category>
        <author><![CDATA[weichao_zju]]></author>
		<guid>http://hi.baidu.com/weichao%5Fzju/blog/item/d9f935d8bc21833432fa1c77.html</guid>
</item>

<item>
        <title><![CDATA[热烈祝贺!]]></title>
        <link><![CDATA[http://hi.baidu.com/weichao%5Fzju/blog/item/0ab0d7f27033b412b17ec573.html]]></link>
        <description><![CDATA[
		
		<font color="#ff0000" size="5">热烈祝贺"SoFTP-超高速千万级ftp文件搜索引擎"荣获《2006’第二届中国开源软件竞赛》铜奖</font> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/weichao%5Fzju/blog/category/ftp%CB%D1%CB%F7%D2%FD%C7%E6">ftp搜索引擎</a>&nbsp;<a href="http://hi.baidu.com/weichao%5Fzju/blog/item/0ab0d7f27033b412b17ec573.html#comment">查看评论</a>]]></description>
        <pubDate>2007-03-29  14:36</pubDate>
        <category><![CDATA[ftp搜索引擎]]></category>
        <author><![CDATA[weichao_zju]]></author>
		<guid>http://hi.baidu.com/weichao%5Fzju/blog/item/0ab0d7f27033b412b17ec573.html</guid>
</item>

<item>
        <title><![CDATA[ftp搜索引擎的设计和实现：4.8 建索引过程]]></title>
        <link><![CDATA[http://hi.baidu.com/weichao%5Fzju/blog/item/cbabfd09a5b68983d0581b38.html]]></link>
        <description><![CDATA[
		
		<p><font color="#ff0000" size="2">欢迎转载，但请注明出处，并给活力链接。谢谢</font></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 现在该来讲建立倒排索引的具体流程和方法了。有了这一章中前面几节的基础，理解这个就变得非常容易。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 在搜集程序运行完以后，我们的目录下各个站点对应了path、attr、info三种文件。<br>
&nbsp;&nbsp;&nbsp;&nbsp; 首先，程序扫描所有的站点，并按字母顺序排序，写到一个叫scanedSite的文件中。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 然后主进程fork出两个子进程，一个子进程负责按顺序扫描attr文件；另一个子进程负责扫描path文件。两个子进程互不干扰，同时进行。主进程等待两个子进程结束。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 负责扫描attr文件的，逐行扫描，每一行对应生成一个Fileinformation结构，以二进制写入到inforindex文件中。<br>
&nbsp;&nbsp;&nbsp;&nbsp; 下面来讲讲Fileinformation结构体中时间这一项是如何表示的。“时间”这一项的定义为<font color="#0000ff">uint createdtime:15;</font> 是个占15bit的整型。其中高5位表示真实的年份减去1970对应的整数，低五位表示日，中间四位表示月份。比如如果一个时间为2005-3-4，则高五位是35（2005-1970），中间四位是3，低五位是4.<br>
&nbsp;&nbsp;&nbsp;&nbsp; 每扫描完一个attr文件，把扫描该attr文件时写入到inforindex文件中的起始索引和终止索引写到info文件中。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 负责扫描path文件的子进程，即扫描path文件中不以”/”开头的每一行（以”/”开头的并不是真正的文件，而是路径），逐一扫描文件，生成双字母倒排索引，写入到对应的索引文件中。生成索引的过程中要注意文件名中含有连续两个中文字符的问题，4.3节已有详细过程及原因，这里不再赘述。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 最后，当主进程等到两个子进程都退出后，计算各个文件夹的大小。（4.6节介绍）<br>
</p> <a href="http://hi.baidu.com/weichao%5Fzju/blog/item/cbabfd09a5b68983d0581b38.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/weichao%5Fzju/blog/category/ftp%CB%D1%CB%F7%D2%FD%C7%E6">ftp搜索引擎</a>&nbsp;<a href="http://hi.baidu.com/weichao%5Fzju/blog/item/cbabfd09a5b68983d0581b38.html#comment">查看评论</a>]]></description>
        <pubDate>2007-03-21  21:53</pubDate>
        <category><![CDATA[ftp搜索引擎]]></category>
        <author><![CDATA[weichao_zju]]></author>
		<guid>http://hi.baidu.com/weichao%5Fzju/blog/item/cbabfd09a5b68983d0581b38.html</guid>
</item>

<item>
        <title><![CDATA[ftp搜索引擎的设计和实现：4.7 mmap函数介绍]]></title>
        <link><![CDATA[http://hi.baidu.com/weichao%5Fzju/blog/item/53224ed96a99442d10df9b5b.html]]></link>
        <description><![CDATA[
		
		<p><font color="#ff0000">欢迎转载，但请注明出处，并给活力链接。谢谢</font></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mmap函数是unix/linux下的系统调用，来看《Unix Netword programming》卷二12.2节对mmap的介绍：<br>
The mmap function maps either a file or a Posix shared memory object into the address space of a process.We use this function for three purposes:<br>
1. with a regular file to provide memory-mapped I/O <br>
2. with special files to provide anonymous memory mappings<br>
3. with shm_open to provide Posix shared memory between unrelated processes</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mmap系统调用并不是完全为了用于共享内存而设计的。它本身提供了不同于一般对普通文件的访问方式，进程可以像读写内存一样对普通文件的操作。而Posix或系统V的共享内存IPC则纯粹用于共享目的，当然mmap()实现共享内存也是其主要应用之一。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mmap系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后，进程可以像访问普通内存一样对文件进行访问，不必再调用read()，write（）等操作。<br>
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我们的程序中大量运用了mmap，用到的正是mmap的这种“像访问普通内存一样对文件进行访问”的功能。实践证明，当要对一个文件频繁的进行访问，并且指针来回移动时，调用mmap比用常规的方法快很多。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 来看看mmap的定义：<br>
<font color="#0000ff">void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);</font><br>
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 参数fd为即将映射到进程空间的文件描述字，一般由open()返回，同时，fd可以指定为-1，此时须指定flags参数中的MAP_ANON，表明进行的是匿名映射（不涉及具体的文件名，避免了文件的创建及打开，很显然只能用于具有亲缘关系的进程间通信）。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; len是映射到调用进程地址空间的字节数，它从被映射文件开头offset个字节开始算起。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; prot参数指定共享内存的访问权限。可取如下几个值的或：PROT_READ（可读）,PROT_WRITE（可写）,PROT_EXEC（可执行）,PROT_NONE（不可访问）。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; flags由以下几个常值指定：MAP_SHARED, MAP_PRIVATE, MAP_FIXED。其中，MAP_SHARED,MAP_PRIVATE必选其一，而MAP_FIXED则不推荐使用。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果指定为MAP_SHARED，则对映射的内存所做的修改同样影响到文件。如果是MAP_PRIVATE，则对映射的内存所做的修改仅对该进程可见，对文件没有影响。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset参数一般设为0，表示从文件头开始映射。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 参数addr指定文件应被映射到进程空间的起始地址，一般被指定一个空指针，此时选择起始地址的任务留给内核来完成。函数的返回值为最后文件映射到进程空间的地址，进程可直接操作起始地址为该值的有效地址。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 看看下面这个图(来自《Unix Netword programming》卷二12.2节)，对mmap进一步加深印象：<br>
</p>
<div forimg="1"><img class="blogimg" border="0" small="0" src="http://hiphotos.baidu.com/weichao_zju/pic/item/0d141ad1821ce33b9a50274d.jpg"></div>
<div forimg="1"></div>
<div forimg="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这里不再详细介绍mmap的参数，读者可参考mmap手册页或者《Unix Netword programming》卷二12.2节获得进一步的信息。</div>
<div forimg="1"></div>
<div forimg="1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 最后，举个例子来结束本节。4.2节说过，Fileinformation数组是以二进制的形式写进一个叫inforindex的文件中。那么，当要访问Fileinformation数组时，代码类似这样：<br>
<font color="#0000ff">struct stat st;<br>
char buffer=” inforindex”;<br>
Fileinformation *_fileinfoIndexptr = NULL;<br>
if(stat(buffer,&amp;st)&lt;0)<br>
{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf(stderr,"error to stat %s\n",buffer);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(-1);<br>
}</font></div>
<div forimg="1"><font color="#0000ff"><font color="#008080">// mmap the inforindex to _fileinfoIndexptr</font><br>
int fd=open(buffer, O_RDONLY);<br>
if(fd&lt;0)<br>
{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("error to open %s\n",buffer);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(-1);<br>
}<br>
_fileinfoIndexptr&nbsp;&nbsp; = (Fileinformation*)mmap(NULL,st.st_size, PROT_READ,MAP_SHARED,fd,0);</font></div>
<div forimg="1"><font color="#0000ff"><br>
if(MAP_FAILED == _fileinfoIndexptr)<br>
{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("error to mmap %s\n",buffer);<br>
close(fd);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(-1);<br>
}<br>
close(fd);</font></div> <a href="http://hi.baidu.com/weichao%5Fzju/blog/item/53224ed96a99442d10df9b5b.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/weichao%5Fzju/blog/category/ftp%CB%D1%CB%F7%D2%FD%C7%E6">ftp搜索引擎</a>&nbsp;<a href="http://hi.baidu.com/weichao%5Fzju/blog/item/53224ed96a99442d10df9b5b.html#comment">查看评论</a>]]></description>
        <pubDate>2007-03-20  21:38</pubDate>
        <category><![CDATA[ftp搜索引擎]]></category>
        <author><![CDATA[weichao_zju]]></author>
		<guid>http://hi.baidu.com/weichao%5Fzju/blog/item/53224ed96a99442d10df9b5b.html</guid>
</item>

<item>
        <title><![CDATA[ftp搜索引擎的设计和实现：4.6 求各个文件夹的大小]]></title>
        <link><![CDATA[http://hi.baidu.com/weichao%5Fzju/blog/item/a1eaaa18b720cbb54bedbc2b.html]]></link>
        <description><![CDATA[
		
		<p><font color="#ff0000">欢迎转载，但请注明出处，并给活力链接。谢谢</font> </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 上面的一节介绍了Mapping这个类。该类主要有两个作用，一是求出各个文件夹的大小，文件夹的大小定义为它所含有的各个文件的大小和文件夹的大小的总和。二是“快照”功能。关于快照，将放在第四部分介绍。这一节主要介绍怎样求得文件夹的大小。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 回顾一下《3.4 信息搜集模块细节》，在那一节中讲述了在attr文件中，如果是文件夹，则大小一项记为-1.如果是文件，大小记为实际的byte数。<br>
而后，所有的attr文件的每一行（即各个站点的每一个文件的属性）都被读入一个Fileinformation数组。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 来看下面这个函数：<br>
<font color="#0000ff">long long oneDirSize(const INDEXTYPE idx,Mapping&amp; mp);</font></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 其中idx是Fileinformation数组的索引。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 该函数首先判断idx对应的是文件还是文件夹。如果是文件，则直接返回该文件的大小。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果是文件夹，则判断它的size是否为-1.如果不是，说明它已经被计算过了，直接返回该大小。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 最后，如果是-1，则利用Mapping类的<font color="#0000ff">subDirFile</font>函数得到该文件夹下的所有文件和文件夹对应于Fileinformation数组的索引，递归调用<font color="#0000ff">oneDirSize</font>函数。实现如下：</p>
<p><br>
<font color="#0000ff">static long long oneDirSize(const INDEXTYPE idx,Mapping&amp; mp)<br>
{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long long totalsize=0;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!mp.isDir(idx))&nbsp;&nbsp;<font color="#008080">// not a dir<br>
</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return mp.getSize(idx);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#339966"> </font><font color="#008080">// This is a dir, but size has been calculated before<br>
</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if((totalsize = mp.getSize(idx)) != -1)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return totalsize;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008080"> // This is a dir, but size has not been calculated<br>
</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; totalsize=0;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector&lt;int&gt; subfileindex;<br>
&nbsp;&nbsp;&nbsp; mp.subDirFile(idx,subfileindex);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int leng = subfileindex.size(); <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;leng;i++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; totalsize+=oneDirSize(subfileindex[i],mp);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // change cur size<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mp.changeSize(idx,totalsize);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return totalsize;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
}</font></p>
<p><font color="#0000ff"><br>
</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 从该函数的实现可以看到，只需要计算最顶层的文件夹，在递归过程中它所含有的子文件夹的大小即被计算了。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 那么哪些是最顶层的文件夹呢？位于ftp根目录“/”下的文件夹就是。所以我们只需要计算那些位于ftp根目录“/”下的文件夹。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在Fileinformation数组中判断哪些是根目录/下的文件夹很简单，只需要判断“所在路径在对应的path文件中的偏移”是否为0.因为/总是出现在path文件中的第一位。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 好了，来看下面的这个函数，该函数计算一个ftp站点所含文件(夹)的总大小。传入的参数ip表示站点名，startindex和endindex分别是该站点的所有文件(夹)在Fileinformation数组中的起始和终结索引。</p>
<p><font color="#0000ff">long long calcdirsize(const char* ip, const INDEXTYPE startindex, const INDEXTYPE endindex)<br>
{<br>
&nbsp;&nbsp;&nbsp;&nbsp; Mapping mp(ip, startindex, endindex, false);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long long totalsize=0;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(INDEXTYPE i=startindex;i&lt;=endindex &amp;&amp; mp.getDiroffset(i)==0;++i)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; totalsize+=oneDirSize(i,mp);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
<p><font color="#0000ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return totalsize;<br>
}</font></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 计算文件夹大小的代码是src/buildindex/calcdirsize.cpp 读者可自行查阅。<br>
</p> <a href="http://hi.baidu.com/weichao%5Fzju/blog/item/a1eaaa18b720cbb54bedbc2b.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/weichao%5Fzju/blog/category/ftp%CB%D1%CB%F7%D2%FD%C7%E6">ftp搜索引擎</a>&nbsp;<a href="http://hi.baidu.com/weichao%5Fzju/blog/item/a1eaaa18b720cbb54bedbc2b.html#comment">查看评论</a>]]></description>
        <pubDate>2007-03-19  22:27</pubDate>
        <category><![CDATA[ftp搜索引擎]]></category>
        <author><![CDATA[weichao_zju]]></author>
		<guid>http://hi.baidu.com/weichao%5Fzju/blog/item/a1eaaa18b720cbb54bedbc2b.html</guid>
</item>

<item>
        <title><![CDATA[ftp搜索引擎的设计和实现：4.5 Mapping类]]></title>
        <link><![CDATA[http://hi.baidu.com/weichao%5Fzju/blog/item/772e8fcc88b9871100e92831.html]]></link>
        <description><![CDATA[
		
		<p><font color="#ff0000" size="2">欢迎转载，但请注明出处，并给活力链接。谢谢</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这一节来分析一个Fileinformation结构体数组对应于各个path文件的类。</p>
<p><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Fileinformation结构体数组是所有文件的基本信息，path文件包含的是目录和文件信息。通过Fileinformation结构体数组中的siteid、diroffset、fileoffset可以精确的定位到对应的path文件得到对应的路径和文件名。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 但是我们需要的不只这个功能。对于一个站点来说，我们还需要诸如以下功能：<br>
“给出目录，得到该目录下的所有文件”<br>
“给出Fileinformation结构体数组的一个索引，如果它是一个目录，得到该目录下的所有文件”<br>
“给出Fileinformation结构体数组的一个索引，如果它是一个目录，得到该目录下的所有文件对应于Fileinformation结构体数组的索引”<br>
&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Mapping类封装了上面所说的这些功能。它的主要接口如下：</p>
<p><font color="#339966"><font color="#008080">// 构造时，传入站点ip、该站点所有的文件在Fileinformation数组中的起始索引和终止索引</font><br>
</font><font color="#0000ff">Mapping(const char* siteip,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const INDEXTYPE startindex,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const INDEXTYPE endindex,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool readonly=true);</font></p>
<p><font color="#008080">// 给定Fileinformation数组的索引，判断该文件是否是目录<br>
</font><font color="#0000ff">inline bool isDir(const INDEXTYPE idx);</font></p>
<p><font color="#008080">//给定Fileinformation数组的索引，返回该文件的大小</font><br>
<font color="#0000ff">inline long long getSize(const INDEXTYPE idx);</font></p>
<p><font color="#008080">//给定Fileinformation数组的索引，返回该文件所在路径在对应的path文件中的偏移</font><br>
<font color="#0000ff">inline int getDiroffset(const INDEXTYPE idx);</font></p>
<p><font color="#008080">//给定一个目录在Fileinformation数组中的索引，返回它所包含的文件在Fileinformation数组中的索引</font><br>
<font color="#0000ff">bool subDirFile(const INDEXTYPE idx,vector&lt;int&gt;&amp; subfilesindex);</font></p>
<p><font color="#008080">//给定一个目录在Fileinformation数组中的索引，返回它所包含的文件名和这些文件在Fileinformation数组中的索引<br>
</font><font color="#0000ff">bool subDirFile(const string&amp; dirpath,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector&lt;FILENAMEANDINDEX&gt;&amp; fileandindex);</font></p>
<p><font color="#008080">//给点一个目录名和文件名，返回它在Fileinformation数组中的索引<br>
</font><font color="#0000ff">bool dirFile(const string&amp; dirpath,const string&amp; dirname,int &amp;index);</font></p>
<p><font color="#008080">//给定Fileinformation数组的索引，改变Fileinformation数组中的项对应的文件大小</font><br>
<font color="#0000ff">void changeSize(const INDEXTYPE idx,const long long size);</font></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="FONT-SIZE: 12pt;  ">Mapping</span><span style="FONT-SIZE: 12pt;  ">类的完整代码在<span>src/mapping/</span>下，读者可自行查阅。</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 那么这个类主要用于哪些地方？请读者们思考一下。下一节我接着分析。<br>
</p> <a href="http://hi.baidu.com/weichao%5Fzju/blog/item/772e8fcc88b9871100e92831.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/weichao%5Fzju/blog/category/ftp%CB%D1%CB%F7%D2%FD%C7%E6">ftp搜索引擎</a>&nbsp;<a href="http://hi.baidu.com/weichao%5Fzju/blog/item/772e8fcc88b9871100e92831.html#comment">查看评论</a>]]></description>
        <pubDate>2007-03-16  23:16</pubDate>
        <category><![CDATA[ftp搜索引擎]]></category>
        <author><![CDATA[weichao_zju]]></author>
		<guid>http://hi.baidu.com/weichao%5Fzju/blog/item/772e8fcc88b9871100e92831.html</guid>
</item>


</channel>
</rss>