<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xml:base="http://www.cellopoint.com/tw" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
 <title>Newest Blogs on Cellopoint</title>
 <link>http://www.cellopoint.com/tw/rss/blogs</link>
 <description>RSS for Blogs</description>
 <language>zh-hant</language>
<item>
 <title>使用 Facebook 登入並取得個資</title>
 <link>http://www.cellopoint.com/tw/media_resources/blogs/2011/11/fb</link>
 <description>&lt;p&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;!--
.c1 {background: #FFCC66;}
.c2 {background: #CCFF99;}
.c3 {background: #99CCFF;}
--&gt;&lt;/style&gt;&lt;/p&gt;
&lt;p&gt;facebook，簡稱 fb，一個社群網路服務網站。許多網站結合了 fb， 來做行銷活動，或是快速新增會員人數。如何將自家的網站與 fb 結合，以下做個簡單的範例 ，讓新加入的會員，可以使用fb的登入，就可以登入自家網站，並取得會員資料。&lt;br /&gt;
1.API 選擇：&lt;br /&gt;
fb官方提供的 API，網頁部份有 javascript、php，手機部份則有 iOS、Android，但由於 fb 好吃新奇又好玩 ，所以，其它語言也各自開發相關的api，如 silverlight、flash、.net、java 等，而本次則是選用 javascript 做為範例。&lt;br /&gt;
2.事前準備：&lt;br /&gt;
2.1.申請 fb 帳號。&lt;br /&gt;
2.2.申請成為開發者人員，如何申請可參考如下網址&lt;br /&gt;
http://sofree.cc/fb-app-1/&lt;br /&gt;
3.開工&lt;br /&gt;
3.1.完成上述 2，進入新建立的應用程式，依序取得 App ID 與 App Secret ，如下圖紅框處，並設定相關資料，如下圖藍框處，本次的測試網站為me.cellopoint.com，故 App 網域與網站位址，分別填入 me.cellopoint.com 與http://me.cellopoint.com，設定好之後，按下儲存鈕&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;/tw/files/image/blogs/fb_001.jpg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;3.2.在 me.cellopoint.com 目錄下，新增 channel.html 與 index.html 兩個檔案，首先開啟 channel.html，裡頭只需加入一段 javascript code&lt;br /&gt;
&amp;lt;script src=&amp;quot;//connect.facebook.net/en_US/all.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
3.3.開啟 index.html，貼上如下的 code，並做紅框處的修改，需注意的是javascript code 必須貼於 &amp;lt;body&amp;gt; 標籤內。&lt;br /&gt;
&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD HTML 4.01 Transitional//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/loose.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;br /&gt;
xmlns:fb=&amp;quot;http://www.facebook.com/2008/fbml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;title&amp;gt;Login&amp;lt;/title&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;fb-root&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;//connect.facebook.net/en_US/all.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
window.fbAsyncInit = function() {&lt;br /&gt;
FB.init({&lt;br /&gt;
&lt;span class=&quot;c1&quot;&gt;appId      : &#039;xxxxxxxxxxx&#039;, // App ID，請輸入 3.1 所又得的 App ID&lt;br /&gt;
channelURL : &#039;//me.cellopoint.com/channel.html&#039;, // 請輸入 3.2 所新增的 channel.html 網址&lt;/span&gt;&lt;br /&gt;
status     : true, // check login status&lt;br /&gt;
cookie     : true, // enable cookies to allow the server to access the session&lt;br /&gt;
oauth      : true, // enable OAuth 2.0&lt;br /&gt;
xfbml      : true  // parse XFBML&lt;br /&gt;
});&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
3.4.登入並取得會員資料&lt;br /&gt;
新增如下 javascript code，說明如下&lt;br /&gt;
a.userID：為個人在 fb 的 id 值，取得如下紅框處，如果個人網站利用fb登入，可以此判別會員。&lt;br /&gt;
b.如欲取得 email，則需設定如下綠框處&lt;br /&gt;
c.取得 name 與 email，使用 FB.api 的 me，如下藍框處&lt;br /&gt;
function FBLogin(){&lt;br /&gt;
FB.login(function(response) {	  &lt;br /&gt;
if (response.authResponse) {&lt;br /&gt;
alert(&#039;登入成功&#039;);&lt;br /&gt;
&lt;span class=&quot;c1&quot;&gt;alert(&#039;UserID&#039; + response.authResponse.userID);&lt;/span&gt;&lt;br /&gt;
FB.api(&lt;span class=&quot;c3&quot;&gt;&#039;/me&#039;&lt;/span&gt;, function(response) {&lt;br /&gt;
alert(&#039;UserName&#039; + response.name);&lt;br /&gt;
alert(&#039;UserEmail&#039; + response.email);&lt;br /&gt;
});&lt;br /&gt;
} else {&lt;br /&gt;
alert(&#039;登入失敗&#039;);&lt;br /&gt;
}&lt;br /&gt;
}, {&lt;span class=&quot;c2&quot;&gt;scope: &#039;email&#039;&lt;/span&gt;});&lt;br /&gt;
}&lt;br /&gt;
3.5.登出：新增如下 javascript code&lt;br /&gt;
function FBLoginOut(){&lt;br /&gt;
FB.logout(function(response) {&lt;br /&gt;
alert(&#039;Logged out.&#039;);&lt;br /&gt;
});&lt;br /&gt;
}&lt;br /&gt;
4.如果要移除掉該應用程式，於個人的 fb 頁面的應用程式選項，找到該應用程式並移除掉即可。&lt;br /&gt;
5.以上參考出處自如下網址&lt;br /&gt;
&lt;a href=&quot;http://developers.facebook.com/docs/reference/javascript/&quot;&gt; http://developers.facebook.com/docs/reference/javascript/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt; &lt;span class=&#039;read-more&#039;&gt;&lt;a href=&quot;http://www.cellopoint.com/tw/media_resources/blogs/2011/11/fb&quot;&gt;閱讀全文&lt;/a&gt;&lt;/span&gt;</description>
 <category domain="http://www.cellopoint.com/tw/taxonomy/term/2">security issue</category>
 <pubDate>Wed, 09 Nov 2011 17:58:39 +0800</pubDate>
 <dc:creator>Hank Chen</dc:creator>
 <guid isPermaLink="false">492 at http://www.cellopoint.com/tw</guid>
</item>
<item>
 <title>Libgtop</title>
 <link>http://www.cellopoint.com/tw/media_resources/blogs/2011/10/libgtop</link>
 <description>&lt;p&gt;如何寫一隻程式來判斷這隻程式在執行階段所佔用的 linux 系統資源，例如 CPU 和記憶體使用率呢? 可以去查看系統中的 /proc/&amp;lt;process id&amp;gt;/stat，或是藉由系統 shell 的 top 指令，但是這兩者都必須花費額外的功夫去分析檔案或介面中的資料。在這邊介紹一個 c 語言的開源函式庫: libgtop，可以幫助我們獲取系統或特定線程所佔用的資源量。&lt;/p&gt;
&lt;p&gt;libgtop 是 GNOME 計畫中的一個函式庫，用來實現 GNOME 桌面環境中的&amp;rdquo;top&amp;rdquo;功能。它依賴於另一個GNOME 的函式庫 glib。目前最新的版本是 2.28，在安裝前必須先安裝 glib 2.6.0 以上版本 以及 intltool 0.35.0 以上版本。&lt;/p&gt;
&lt;p&gt;一般來說，CPU 的使用率，是根據 CPU 花費在各種不同模式的時間所計算的。這些時間通常可分為user mode, nice mode, system(kernel) mode 和 idle mode，而使用 libgtop 的 API 可以獲取系統 boot 到目前為止，各種 mode 所佔用的時間(clock click 次數)。舉例而言，可以利用下面的程式碼來計算出系統 CPU 的使用率:&lt;/p&gt;
&lt;p&gt;#include &amp;lt;glibtop&amp;gt;&lt;br /&gt;
#include &amp;lt;glibtop/cpu.h&amp;gt;&lt;/p&gt;
&lt;p&gt;double cpu_rate;&lt;br /&gt;
int dt, du, dn, ds;&lt;br /&gt;
glibtop_cpu cpu_begin,cpu_end;&lt;br /&gt;
glibtop_get_cpu(&amp;amp;cpu_begin);&lt;br /&gt;
sleep(1);&lt;br /&gt;
glibtop_get_cpu(&amp;amp;cpu_end);&lt;br /&gt;
dt = cpu_end.total - cpu.begin.total;&lt;br /&gt;
du = cpu_end.user - cpu.begin.user;&lt;br /&gt;
dn = cpu_end.nice - cpu.begin.nice;&lt;br /&gt;
ds = cpu_end.sys - cpu.begin.sys;&lt;br /&gt;
cpu_rate = 100.0 * (du+dn+ds) / dt&lt;/p&gt;
&lt;p&gt;注意 CPU 使用率的計算必須根據兩個時間點的 click 次數的差，所以必須截取兩次這個資訊後再相減。而memory 的觀測就比較單純，可以一次獲得。例如:&lt;/p&gt;
&lt;p&gt;#include &amp;lt;glibtop&amp;gt;&lt;br /&gt;
#include &amp;lt;glibtop/mem.h&amp;gt;&lt;/p&gt;
&lt;p&gt;double mem_rate;&lt;br /&gt;
glibtop_mem memory;&lt;br /&gt;
glibtop_get_mem(&amp;amp;memory);&lt;br /&gt;
mem_rate = 100.0 * memory.used / memory.total;&lt;/p&gt;
&lt;p&gt;libgtop 可以觀測的資源種類相當多，除了上例中介紹的系統 CPU 和記憶體以外，還包括特定線程的 CPU 和記憶體、swap、檔案系統、網路介面等等。詳細的 API 及資料結構可以參考 GNOME 的官方網站： &lt;a href=&quot;http://developer.gnome.org/libgtop/&quot;&gt;http://developer.gnome.org/libgtop/&lt;/a&gt;&lt;/p&gt; &lt;span class=&#039;read-more&#039;&gt;&lt;a href=&quot;http://www.cellopoint.com/tw/media_resources/blogs/2011/10/libgtop&quot;&gt;閱讀全文&lt;/a&gt;&lt;/span&gt;</description>
 <category domain="http://www.cellopoint.com/tw/taxonomy/term/12">software engineering</category>
 <pubDate>Mon, 03 Oct 2011 11:10:14 +0800</pubDate>
 <dc:creator>David Lee</dc:creator>
 <guid isPermaLink="false">488 at http://www.cellopoint.com/tw</guid>
</item>
<item>
 <title>Google File System 介紹</title>
 <link>http://www.cellopoint.com/tw/media_resources/blogs/2011/08/gfs</link>
 <description>&lt;!--&lt;p&gt;&lt;iframe src=&quot;http://www.facebook.com/plugins/like.php?href=&amp;amp;layout=standard&amp;amp;show_faces=true&amp;amp;width=450&amp;amp;action=like&amp;amp;font=verdana&amp;amp;colorscheme=light&amp;amp;height=35&quot; scrolling=&quot;no&quot; frameborder=&quot;0&quot; allowtransparency=&quot;true&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;--&gt;
&lt;p&gt;Google 之所以能獨霸搜尋引擎市場，一方面是依靠 PageRank 技術所提供的優良搜尋排序，另一方面則仰賴其文件儲存系統的優良效率。Google 設計了一套獨特的分散式檔案系統以滿足其龐大的儲存需求，也就是所謂的 Google File System (簡稱 GFS)。Google 並沒有將 GFS 當做開源軟體釋出，不過還是公布了一些技術細節，包含一篇官方論文。&lt;/p&gt;
&lt;p&gt;與傳統的分散式檔案系統相比，GFS 有兩個主要的不同點。首先，設備的失效被視為正常的現象而非意外。所謂的失效包括了應用程式的錯誤、作業系統的錯誤、人為操作的錯誤、乃至於硬體或網路的問題。既然連昂貴的硬碟設備也不可能百分之百排除發生錯誤的可能性，Google乾脆使用多個廉價的磁碟機來組成他們的儲存設備。而為了對抗設備的失效，GFS 包含了監視、錯誤偵測、容錯以及自動修復的機制。&lt;/p&gt;
&lt;p&gt;其次，資料大多只會被追加到文件的末端，鮮少會修改或刪除原本存在的檔案。已寫入的資料通常只需要可讀 (readable) 不需要可寫 (writable)，而且通常是按照順序且大規模的讀取，一次操作便可能讀取數百 KB甚至 MB 以上的資料。要特別注意到的是，GFS 預期所保存的檔案通常都是數百 MB 甚至 GB 以上的文件，小型的文件會被支持但不會被優化。&lt;/p&gt;
&lt;p&gt;GFS 處理客戶端所下要求的方式是採類似 supernode (Master) 與分散式結點 (Chunkserver) 的架構。真正的數據資料儲存在 Chunkserver上，並且定期將其狀態報告給 Master。當客戶端需要讀取某個檔案時，要先向 Master 發出要求，Master 會考慮 Chunkserver 是否為閒置狀態，若為閒置則將 Chunkserver 的位置回報給 client，於是 client 就可以對 Chunkserver 中的檔案進行操作。&lt;/p&gt;
&lt;p&gt;GFS 支持了必需提供超大文件量與超大流量的 Google 搜尋引擎服務，同時建構於 GFS 之上的 BigTable 資料庫技術也是 Gmail、Google Maps、Youtube 乃至於其他許多 Google 應用軟體或雲端服務的基礎，可以說是雲端時代的殺手級技術。&lt;/p&gt;
&lt;p&gt;礙於篇幅，更多的 GFS 細節可以參考: &lt;a href=&quot;http://labs.google.com/papers/gfs.html&quot;&gt;http://labs.google.com/papers/gfs.html&lt;/a&gt;&lt;/p&gt; &lt;span class=&#039;read-more&#039;&gt;&lt;a href=&quot;http://www.cellopoint.com/tw/media_resources/blogs/2011/08/gfs&quot;&gt;閱讀全文&lt;/a&gt;&lt;/span&gt;</description>
 <category domain="http://www.cellopoint.com/tw/taxonomy/term/12">software engineering</category>
 <pubDate>Tue, 02 Aug 2011 10:28:44 +0800</pubDate>
 <dc:creator>David Lee</dc:creator>
 <guid isPermaLink="false">479 at http://www.cellopoint.com/tw</guid>
</item>
<item>
 <title>PHP 函數實作 Semaphore</title>
 <link>http://www.cellopoint.com/tw/media_resources/blogs/2011/07/php</link>
 <description>&lt;p&gt;Semaphore 是一個可變或抽象的資料型態，在並行計算環境中，若有多個行程對一個共用資源，將可提供簡單有用的控制存取。&lt;/p&gt;
&lt;p&gt;可以把 semaphore 想成是一個記錄，有多少單位的特殊資源是可使用的，加上操作安全地(即沒有競爭危害)調整那個紀錄，且那是有需要等待的直到一個單位的資源變得可使用。&lt;/p&gt;
&lt;p&gt;Semaphore是有用的工具來預防競爭危害和死鎖; 然而，他們的用途絕不是保證程式可以從這些問題中解脱。資源允許任意數量的 semaphore 叫 counting semaphores；值只有 1 或 0 的 semaphore (或 locked/unlocked、unavailable/available)稱 binary semaphores。&lt;/p&gt;
&lt;p&gt;下面為 PHP 的 semaphore 函數&lt;br /&gt;
int ftok (string $pathname, string $proj) &amp;ndash; 將可存取的路徑和方案編號轉換成 System V 可存取的 IPC key。&lt;/p&gt;
&lt;p&gt;bool sem_acquire (resource $sem_identifier) - 向信號機要求，信號機會減少一個資源數，並進入臨界區。&lt;/p&gt;
&lt;p&gt;resource sem_get (int $key [, int $max_acquire = 1 [, int $perm = 0666 [, int $auto_release = 1 ]]]) - 取得一個新的信號機。&lt;/p&gt;
&lt;p&gt;bool sem_release (resource $sem_identifier) - 向信號機通知釋放一個資源數，並離開臨界區。&lt;/p&gt;
&lt;p&gt;bool sem_remove (resource $sem_identifier) - 移除一個信號機。&lt;/p&gt;
&lt;p&gt;resource shm_attach (int $key [, int $memsize [, int $perm ]]) - 回傳一個可以存取 system V 共享記憶體的編號。&lt;/p&gt;
&lt;p&gt;bool shm_detach (resource $shm_identifier) - 中止對共享記憶體的連結。&lt;/p&gt;
&lt;p&gt;mixed shm_get_var (resource $shm_identifier, int $variable_key) - 取得共享記憶體中指定的變數值。&lt;br /&gt;
&lt;br /&gt;
bool shm_has_var (resource $shm_identifier, int $variable_key) - 檢查共享記憶體裡是否存在該鍵值。&lt;/p&gt;
&lt;p&gt;bool shm_put_var (resource $shm_identifier, int $variable_key, mixed $variable) - 增加或修改共享記憶體中的變數值。&lt;/p&gt;
&lt;p&gt;bool shm_remove_var (resource $shm_identifier, int $variable_key) - 移除指定的變數名稱。&lt;/p&gt;
&lt;p&gt;bool shm_remove (resource $shm_identifier) &amp;ndash; 移除共享記憶體。&lt;/p&gt; &lt;span class=&#039;read-more&#039;&gt;&lt;a href=&quot;http://www.cellopoint.com/tw/media_resources/blogs/2011/07/php&quot;&gt;閱讀全文&lt;/a&gt;&lt;/span&gt;</description>
 <category domain="http://www.cellopoint.com/tw/taxonomy/term/12">software engineering</category>
 <pubDate>Fri, 15 Jul 2011 19:07:43 +0800</pubDate>
 <dc:creator>Ruby Lin</dc:creator>
 <guid isPermaLink="false">477 at http://www.cellopoint.com/tw</guid>
</item>
<item>
 <title>GNU libextractor</title>
 <link>http://www.cellopoint.com/tw/media_resources/blogs/2011/07/GNU</link>
 <description>&lt;h3&gt;Introduction&lt;/h3&gt;
&lt;p&gt;GNU libextractor 是一個種用來從 file 中提取 meta data 的 library。他的設計為以輔助程式庫的方式來執行提取文件實際內容，Meta data 格式的資料有下列 (mime type, image dimensions, color depth, recording frequency)，GNU libextractor 主要是被我們用來提取 meta data 之用。目前，GNU libextractor 支持以下格式：HTML, PDF, PS, OLE2 (DOC, XLS, PPT), OpenOffice (sxw), StarOffice (sdw), DVI, MAN, FLAC, MP3 (ID3v1 and ID3v2), NSF(E) (NES music), SID (C64 music), OGG, WAV, EXIV2, JPEG, GIF, PNG, TIFF, DEB, RPM, TAR(.GZ), ZIP, ELF, S3M (Scream Tracker 3), XM (eXtended Module), IT (Impulse Tracker), FLV, REAL, RIFF (AVI), MPEG, QT and ASF. 此外，還有各種額外的 MIME 類型檢測。&lt;/p&gt;
&lt;p&gt;GNU libextractor 是免費軟件，可以下載下來修改以及發布。&lt;br /&gt;
GNU libextractor 使用 plugin 來處理各種文件格式。從技術上講一個 plugin 可以支持多種文件格式，但大多數 plugin 只支持一個特定的格式。默認情況下，GNU libextractor 將使用所有在安裝目錄下發現的可用 plugin。應用程序可以要求使用特定 plugin 或只有排除某些 plugin。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example for using dynamic library&lt;/strong&gt;&lt;/p&gt;
&lt;table width=&quot;350&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; align=&quot;center&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&quot;rteleft&quot;&gt;// hello.c&lt;br /&gt;
            #include &amp;lt;extractor.h&amp;gt;&lt;br /&gt;
            int main()&lt;br /&gt;
            {&lt;br /&gt;
            struct EXTRACTOR_PluginList *el;&lt;br /&gt;
            el = EXTRACTOR_plugin_load_defaults (EXTRACTOR_OPTION_DEFAULT_POLICY);&lt;br /&gt;
            // ...&lt;br /&gt;
            EXTRACTOR_plugin_remove_all (el);&lt;br /&gt;
            return 0;&lt;br /&gt;
            }&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;執行以下指令 &lt;strong&gt;compile&lt;/strong&gt; &lt;br /&gt;
$ gcc \ -I/Library/Frameworks/Extractor.framework/Versions/Current/include \&lt;br /&gt;
-o hello hello.c \&lt;br /&gt;
-L/Library/Frameworks/Extractor.framework/Versions/Current/lib \&lt;br /&gt;
-lextractor&lt;/p&gt;
&lt;h3&gt;Plugin management&lt;/h3&gt;
&lt;p&gt;C Struct: EXTRACTOR_PluginList&lt;br /&gt;
&lt;span&gt;建立一組 plugin&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Function: void EXTRACTOR_plugin_remove_all (struct EXTRACTOR_PluginList *plugins)&lt;br /&gt;
&lt;span&gt;刪除所有給定 plugin 列表&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Function: struct EXTRACTOR_PluginList * EXTRACTOR_plugin_remove (struct EXTRACTOR_PluginList *plugins, const char*name)&lt;br /&gt;
&lt;span&gt;刪除給定 plugin 列表例如 mime 中的 mpeg&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Function: struct EXTRACTOR_PluginList * EXTRACTOR_plugin_add (struct EXTRACTOR_PluginList *plugins, const char* name,const char* options, enum EXTRACTOR_Options flags)&lt;br /&gt;
&lt;span&gt;增加給定 plugin 列表&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Function: struct EXTRACTOR_PluginList * EXTRACTOR_plugin_add_config (struct EXTRACTOR_PluginList *plugins, const char* config, enum EXTRACTOR_Options flags)&lt;br /&gt;
&lt;span&gt;根據 config string load 或是 unload 或是修改已存在的列表&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Function: struct EXTRACTOR_PluginList * EXTRACTOR_plugin_add_defaults (enum EXTRACTOR_Options flags)&lt;br /&gt;
&lt;span&gt;載入所有在 plugin 資料夾下的預設 plugin 列表&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;Example for a minimal extract method&lt;/h3&gt;
&lt;p&gt;以下範例告訴我們如何利用 plugin 解讀出 MIME type&lt;/p&gt;
&lt;table width=&quot;350&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; align=&quot;center&quot;&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;
            &lt;p&gt;int&lt;br /&gt;
            EXTRACTOR_mymime_extract&lt;br /&gt;
            (const char *data,&lt;br /&gt;
            size_t data_size,&lt;br /&gt;
            EXTRACTOR_MetaDataProcessor proc,&lt;br /&gt;
            void *proc_cls,&lt;br /&gt;
            const char * options)&lt;br /&gt;
            {&lt;br /&gt;
            if (data_size &amp;lt; 4)&lt;br /&gt;
            return 0;&lt;br /&gt;
            if (0 != memcmp (data, &amp;quot;\177ELF&amp;quot;, 4))&lt;br /&gt;
            return 0;&lt;br /&gt;
            if (0 != proc (proc_cls, &lt;br /&gt;
            &amp;quot;mymime&amp;quot;,&lt;br /&gt;
            EXTRACTOR_METATYPE_MIMETYPE,&lt;br /&gt;
            EXTRACTOR_METAFORMAT_UTF8,&lt;br /&gt;
            &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
            &amp;quot;application/x-executable&amp;quot;,&lt;br /&gt;
            1 + strlen(&amp;quot;application/x-executable&amp;quot;)))&lt;br /&gt;
            return 1;&lt;br /&gt;
            /* more calls to &#039;proc&#039; here as needed */&lt;br /&gt;
            return 0;&lt;br /&gt;
            }&lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;Internal utility functions&lt;/h3&gt;
&lt;p&gt;有些實用的內部開發 API &lt;br /&gt;
&amp;ldquo;convert_numeric.h&amp;rdquo; 定義了各種數字的轉換功能（特別是轉換為浮點數）。&lt;br /&gt;
&amp;ldquo;unzip.h&amp;rdquo; 定義了一個訪問壓縮文件的 API。&lt;br /&gt;
&amp;ldquo;pack.h&amp;rdquo; 可以把有 integer 的 struts 分解順便也可以把 big/little endian 轉成 host byte order。&lt;br /&gt;
&amp;ldquo;convert.h&amp;rdquo; 提供了一個函數進行所需之字符集轉換。&lt;br /&gt;
Function: char * EXTRACTOR_common_convert_to_utf8 (const char *input, size_t len, const char * charset) 可以用來方便地從任何字符集轉換為 UTF - 8 文本。&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;總之，對於訊息解析平凡的我們來說，GNU libextractor 不只幫助了我們找到檔案的正確格式，還可以撰寫各種 plugin 工具，分析各種文字格式，找到相對應的 MIME type。這對 email 這塊領域而言，可說是不可或缺的一項工具。&lt;/p&gt; &lt;span class=&#039;read-more&#039;&gt;&lt;a href=&quot;http://www.cellopoint.com/tw/media_resources/blogs/2011/07/GNU&quot;&gt;閱讀全文&lt;/a&gt;&lt;/span&gt;</description>
 <category domain="http://www.cellopoint.com/tw/taxonomy/term/12">software engineering</category>
 <pubDate>Mon, 04 Jul 2011 13:43:00 +0800</pubDate>
 <dc:creator>Shawn Lin</dc:creator>
 <guid isPermaLink="false">473 at http://www.cellopoint.com/tw</guid>
</item>
<item>
 <title>What is memcache?</title>
 <link>http://www.cellopoint.com/tw/media_resources/blogs/2011/06/memcache</link>
 <description>&lt;p&gt;今天我要介紹一個對於存取資料庫相當有用的技術 - Memcache.&lt;/p&gt;
&lt;p&gt;Memcache 是一種分散式記憶體快取系統，對於現在熱門的雲端系統也是相當有用的。 它最基本的概念式用 key-based 的資料結構來存取資料到記憶體內部。 原先這個概念來自於 Brad Fitzpatrick，他最早用在一家叫做 LiveJournal.com(2003) 的公司，因為效果不錯，而又加以發揚光大。 現在有更多的大公司有在用這項服務：LiveJournal、Wikipedia、Flickr、Twitter、Youtube、Digg、WordPress.com&amp;hellip;etc. 它的好處在，可以縮減大部分存取資料庫的時間轉而到存取記憶體上面，就算資料沒有在記憶體上面對於要到後方存取資料庫也是相當的容易設計。 雖然它有 key-based 快取還有分散式記憶體功能，但是對於存取限制這點必須由建構者自己決定。 這項技術效果最好的地方當然就是把常用的資料寫到記憶體內部，那麼下次存取的時候就近乎不用等待時間。 這概念有點像是當你上網的時候，網站會將網站大部分的圖片資料先暫存到你電腦內，等你下次又再存取這個網站的時候，速度會大幅提升是一樣道理。Memcache 也是用一樣的概念，它拿你電腦的記憶體來加速存取，它可以拿整個網路的空閒記憶體來存取，讓你可以在同一個網路架構下共同存取使用到， 另外一個特點就是你想要增加多少記憶體使用就可以增加多少(當然你需要充足的記憶體)，甚至它會將所有記憶體區塊視為同一個記憶體，這就結合著前面所敘述著，網路上的記憶體只要你可以用你就可以將全體合併執行。而理論上它的設計這些行為應該都在 O(1) 可以完成。&lt;/p&gt;
&lt;p&gt;現在我來給一個簡單的範例來敘說有 Memcache 使用上的差異 我們每天從一台電腦存取資料，如果我們想加入就會想要再加一台機器，但是要怎樣才會有效率?&lt;/p&gt;
&lt;p class=&quot;rtecenter&quot;&gt;&lt;img width=&quot;500&quot; height=&quot;258&quot; alt=&quot;&quot; src=&quot;/tw/files/image/blogs/memcache.jpg&quot; /&gt;&lt;/p&gt;
&lt;p class=&quot;rteleft&quot;&gt;圖片1，我們有兩台機器兩個分開的記憶體，為了確保兩台資料相同不會有不一致情形發生，所以我們會讓兩台記憶體都存取一樣的資料， 結果導致只是電腦 CPU 運作很快，但是記憶體沒有有效率的使用，這種設置效率很差。&lt;/p&gt;
&lt;p&gt;圖片2，我們有兩台機器，但是透過 Memcache 來結合兩邊的記憶體，所以我們記憶體是共存使用的，不用擔心不一致的情形， 而且空間還加倍使用，整個生活變得更美好了!!&lt;/p&gt;
&lt;p&gt;那我們到底該怎樣使用 Memcache 比較好? 以目前較有意義的使用方式是，如果你的存取資料庫充滿著&amp;rdquo;SELECT * from XXX&amp;rdquo;， 表示你常常要所有的資料而且量不少，而且如果又是常常重複的資料，那你就可以使用Memcache使用的相當快樂。 這邊給一個簡單的分析，你如果要用 Memcache 必須要考慮幾個要點：1. 搜尋的時間 2. 擊中率 3. 檔案存在時間，當然你需要花費額外的人力時間去寫程式來增加這段效率，不過比較起結果，這算是常態時間 (Constant time) 的考量吧?&lt;/p&gt;
&lt;p&gt;我再給予一個簡單的流程來說明要如何建構你的系統跟 Memcache 還有資料庫運作 假設你現在有很多台伺服器，現在想要連結這幾台伺服器有更有效率的應用記憶體。 以下是一個簡單的流程: 你的客戶們來詢問伺服器資料，你的伺服器一開始會先去詢問 Memcache，如果資料不存在於 Memcache，這時候在去詢問 Database，等到找到資料的時候，記得要將資料再寫回去 Memcache，這就是一個簡單的標準流程。系統剛開始跑 或許會有陣痛期，等只要時間久了，整體速度應該是向上提升才對。&lt;/p&gt;
&lt;p class=&quot;rtecenter&quot;&gt;&lt;img width=&quot;450&quot; height=&quot;529&quot; alt=&quot;&quot; src=&quot;/tw/files/image/blogs/flow.jpg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;再上面的例子其實你可以看的出來 Memcache在實做上是一個網路的 daemon 大多數人會配合著 PHP或是 C/C++來跟 Memcache 溝通 我使用的 Linux 系統，如果你想要用 C/C++ 來建構，基本上你必須先安裝幾個程式：1. libevent 2.Memcache 3. libmemcache&lt;/p&gt;
&lt;p&gt;想要了解更詳細的操作跟內容請參造 Memcache官網: &lt;a href=&quot;http://memcached.org/&quot;&gt;http://memcached.org/&lt;/a&gt;&lt;/p&gt; &lt;span class=&#039;read-more&#039;&gt;&lt;a href=&quot;http://www.cellopoint.com/tw/media_resources/blogs/2011/06/memcache&quot;&gt;閱讀全文&lt;/a&gt;&lt;/span&gt;</description>
 <category domain="http://www.cellopoint.com/tw/taxonomy/term/12">software engineering</category>
 <pubDate>Thu, 23 Jun 2011 16:52:17 +0800</pubDate>
 <dc:creator>HH Tu</dc:creator>
 <guid isPermaLink="false">472 at http://www.cellopoint.com/tw</guid>
</item>
<item>
 <title>甚麼是 Node.js?</title>
 <link>http://www.cellopoint.com/tw/media_resources/blogs/2011/06/Node_js</link>
 <description>&lt;p&gt;傳統上，JavaScript 只在網頁瀏覽器執行，但由於 CommonJS 專案，最近已經有相當多的興趣也把它拿到伺服器端。其他伺服器端 JavaScript 環境，包括 Jaxer 和 Narwhal。然而，Node.js 有點不同於這些解決方式，因為它是事件基礎 (event-based) 而不是執行序基礎 (thread based)，像 Apache 這種被用來服務 PHP 和其他 CGI 語言的網頁伺服器是執行序基礎，因為它們為每個近來的需求產生一個系統執行序。雖然這對很多應用程式是沒問題，但執行序基礎在很多諸如為了服務及時應用程式需要長久的 (long-lived) 連線，像 Friendfeed 或 Google Wave，並沒有很好地擴展。&lt;/p&gt;
&lt;p&gt;Node.js 使用事件迴圈取代執行序，且能夠擴充到同時有上百萬的連線，它利用伺服器花最多的時間在等待讀取與寫入操作的事實，像從硬碟讀取檔案、存取額外的網頁服務或等待檔案上傳完成，因為這些作業比記憶體作業慢很多。每個讀取與寫入操作在 Node.js 是非同期，意指當讀取與寫入操作發生時，伺服器能夠繼續處理進來的需求。JavaScript 是非常適合事件基礎的程式設計，因為它有匿名函數 (anonymous functions) 和封絕 (closure)，且 JavaScript 開發者已經知道如何以這種方式編程，這種事件基礎模式讓 Node.js 很快，且讓擴充及時應用程式很容易。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://docs.pylonsproject.org/projects/pyramid/1.0/narr/introduction.html&quot;&gt;http://docs.pylonsproject.org/projects/pyramid/1.0/narr/introduction.html&lt;/a&gt;&lt;/p&gt; &lt;span class=&#039;read-more&#039;&gt;&lt;a href=&quot;http://www.cellopoint.com/tw/media_resources/blogs/2011/06/Node_js&quot;&gt;閱讀全文&lt;/a&gt;&lt;/span&gt;</description>
 <category domain="http://www.cellopoint.com/tw/taxonomy/term/12">software engineering</category>
 <pubDate>Fri, 17 Jun 2011 10:19:43 +0800</pubDate>
 <dc:creator>Paul Chien</dc:creator>
 <guid isPermaLink="false">471 at http://www.cellopoint.com/tw</guid>
</item>
<item>
 <title>LDAP</title>
 <link>http://www.cellopoint.com/tw/media_resources/blogs/2011/06/LDAP</link>
 <description>&lt;p&gt;試想兩個不同的問題：其一，一個上千人的龐大組織，擁有許多不同的部門與 IT 資源，要如何維護一個便於更新且組織成員們易於查詢的線上通訊錄? 其二，一個必須同時維護多個不同系統 (可能包含 linux 登入、apache、samba、mail service 等等) 的 MIS 人員，要如何維護多組不同的帳號密碼，甚至必須定期更新它們?  這兩個問題看來毫不相干，可是都可以使用同一個方案來解決：LDAP (Lightweight Directory Access Protocol)。&lt;/p&gt;
&lt;p&gt;LDAP 是一個參考線上目錄服務 (Directory Service) 的協定，其經由 X.500 改造而來，省略了 X.500 許多繁瑣的細節，成為了一個能夠建構於 IP 網路上、彈性而方便的網路協定。對前文的問題一而言，LDAP 充滿彈性的設計讓我們能夠將組織資源整理成目錄型式的資料庫；而對於問題二而言，LDAP 提供了一個標準化的介面供不同的應用程式參考，因而很容易整合多種不同應用服務的組態配置 (configuration)。&lt;/p&gt;
&lt;p&gt;以宏觀的角度來看，LDAP 將多筆資料以樹狀結構做儲存，稱為 DIT (Directory Information Tree)。整個 DIT 可以切割成許多子樹，每個子樹都可以儲存在不同的 LDAP 伺服器上，以達到分散式架構的目的。其中，每一筆資料都會有一個獨一無二的 Distinguished Name (DN)，就像是一般檔案系統中的「絕對路徑」，用來標記這筆資料在 DIT 中的位址。&lt;/p&gt;
&lt;p&gt;以微觀的角度來看，LDAP 中每一筆資料都符合一種特殊的schema，並且可以轉換成 LDIF (LDAP Data Interchange Format) 格式以便閱讀 (注意實際上資料的儲存方式可能是binary 的)。在 LDIF 格式中，每一筆資料都會擁有多個不同的「屬性」，每種屬性則會擁有一到多個不同的「值」。一筆資料可能擁有哪些屬性，必須根據它所屬的物件類別 (objectClass)。例如，類別為「員工」的資料可能會有「姓名」、「所屬部門」、「郵件位址」等屬性，而類別為「部門」的資料則可能有「主管」、「所屬員工」等屬性。其中，每一筆資料都一定會有 DN 和 objectClass 這兩個屬性，至於其他「應有」和「可有」的屬性，則由其 objectClass 而定。&lt;/p&gt;
&lt;p&gt;要在 LDAP server 上查詢資料時，可以把查詢 (query) 包裝成LDAP URL 的格式:&lt;/p&gt;
&lt;p&gt;ldap://&amp;quot; [ &amp;lt;host&amp;gt; ]&amp;quot;/&amp;quot; &amp;lt;dn&amp;gt; [ &amp;quot;?&amp;quot; &amp;lt;attributes&amp;gt;[ &amp;quot;?&amp;quot; &amp;lt;scope&amp;gt; &amp;quot;?&amp;quot; &amp;lt;filter&amp;gt; ] ]&lt;br /&gt;
&amp;lt;host&amp;gt; ::= &amp;lt;hostname&amp;gt;[ &amp;quot;:&amp;quot; &amp;lt;port&amp;gt; ]					&lt;br /&gt;
&amp;lt;attributes&amp;gt; ::= NULL | &amp;lt;attributelist&amp;gt;		&lt;br /&gt;
&amp;lt;attributelist&amp;gt; ::= &amp;lt;attributetype&amp;gt;| &amp;lt;attributetype&amp;gt;[ &amp;quot;,&amp;quot; &amp;lt;attributelist&amp;gt; ]&lt;br /&gt;
&amp;lt;scope&amp;gt; ::= &amp;quot;base&amp;quot; | &amp;quot;one&amp;quot; | &amp;quot;sub&amp;quot;&lt;/p&gt;
&lt;p&gt;●	host: server 的 IP 位址&lt;br /&gt;
●	dn: 搜尋起點的 dn&lt;br /&gt;
●	attributes: 希望回傳的屬性有哪些&lt;br /&gt;
●	scope: 搜尋的範圍(單一節點、第一代的子節點、或是整個子樹)&lt;br /&gt;
●	filter: 搜尋條件&lt;/p&gt;
&lt;p&gt;例如: ldap://cellopoint.com/ou=rd,ou=unit,ou=company,dc=cellopoint,dc=com?mail?sub?uid=david&lt;br /&gt;
會回傳 cellopoint 公司中、rd 部門下、id 為 &amp;rdquo;david&amp;rdquo; 的員工的email。&lt;/p&gt;
&lt;p&gt;目前最常被使用的兩個 LDAP 軟體為 openldap 和 Microsoft Active Directory。前者是 open source 的軟體，對 LDAP 有興趣者不妨測試看看，也許就會發現一些原本很繁瑣的 MIS 工作頓時變得輕鬆不少喔！&lt;/p&gt; &lt;span class=&#039;read-more&#039;&gt;&lt;a href=&quot;http://www.cellopoint.com/tw/media_resources/blogs/2011/06/LDAP&quot;&gt;閱讀全文&lt;/a&gt;&lt;/span&gt;</description>
 <category domain="http://www.cellopoint.com/tw/taxonomy/term/12">software engineering</category>
 <pubDate>Thu, 09 Jun 2011 10:14:35 +0800</pubDate>
 <dc:creator>David Lee</dc:creator>
 <guid isPermaLink="false">470 at http://www.cellopoint.com/tw</guid>
</item>
<item>
 <title>Web Application Frameworks</title>
 <link>http://www.cellopoint.com/tw/media_resources/blogs/2011/05/Web_Application_Frameworks</link>
 <description>&lt;p&gt;&amp;nbsp;由於網路以及網路服務的使用率越來越大，網站在 Web 2.0 時代不再只支持靜態內容。網站的內容已成為動態讓使用者可以操作實時的工作，例如檢查和發送郵件。我們的網絡工程因為不斷添加新功能讓它的規模變的龐大和複雜。&lt;/p&gt;
&lt;p&gt;Web Application Frameworks 提供軟體結構的模型，幫助我們分類和管理網路應用程式不同的組件。他們還提供一些有用的 libraries，例如：訪問數據庫，呈現模板和 session 管理。&lt;/p&gt;
&lt;p&gt;許多 Web Application Frameworks 使用 Model-View-Controller（MVC）的結構來定義網路應用程式邏輯上的組件。以下是 model，view 和 controller 的解釋：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Model&lt;/strong&gt;&lt;br /&gt;
應用程式的 model 是用來處理系統的數據。換句話說，它包括數據和用來處理數據的函數。Controllers 和 views 會透過 model 獲取和更改數據。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;View &lt;/strong&gt;&lt;br /&gt;
View 是呈現給使用者看到的應用程式組件，換句話說，使用者界面。使用者要使用這個界面與應用程式互動。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Controller &lt;/strong&gt;&lt;br /&gt;
Controller 是用來處理使用者的 request 並返回 response 給使用者。它會透過 model 獲得所需要的數據，把數據準備成一個合適的格式，插入到 view 裡和呈現 view 給使用者。&lt;/p&gt;
&lt;p&gt;一個典型的 request 到服務器的情況如下：使用者透過界面發送一個 request 到服務器。主 controller 會處理這個 request 將它委託給適當的 controller 和把控制傳給這個 controller。被委託的 controller 會跟 model 互動來獲取或更改數據，呈現 view，並將控制還給主 controller。主 controller 會返回呈現的 view。使用者與界面互動並發送新的請求時，這循環就會重複。&lt;/p&gt;
&lt;p&gt;References:&lt;br /&gt;
[1] Web application framework. (2011, May 28). In Wikipedia, The Free Encyclopedia. Retrieved 15:23, May 30, 2011, from http://en.wikipedia.org/w/index.php?title=Web_application_framework&amp;amp;oldid=431373642&lt;br /&gt;
[2] Model&amp;ndash;view&amp;ndash;controller. (2011, May 26). In Wikipedia, The Free Encyclopedia. Retrieved 17:12, May 30, 2011, from http://en.wikipedia.org/w/index.php?title=Model%E2%80%93view%E2%80%93controller&amp;amp;oldid=430946706&lt;/p&gt; &lt;span class=&#039;read-more&#039;&gt;&lt;a href=&quot;http://www.cellopoint.com/tw/media_resources/blogs/2011/05/Web_Application_Frameworks&quot;&gt;閱讀全文&lt;/a&gt;&lt;/span&gt;</description>
 <category domain="http://www.cellopoint.com/tw/taxonomy/term/14">Internet</category>
 <pubDate>Tue, 31 May 2011 14:32:46 +0800</pubDate>
 <dc:creator>June Huang</dc:creator>
 <guid isPermaLink="false">468 at http://www.cellopoint.com/tw</guid>
</item>
<item>
 <title>Protocol Buffers (Google 專用的通訊協定)</title>
 <link>http://www.cellopoint.com/tw/media_resources/blogs/2011/05/Protocol_Buffers</link>
 <description>&lt;p&gt;&lt;strong&gt;&amp;nbsp;Introduction 簡介&lt;/strong&gt;&lt;br /&gt;
Protocol buffers 是一個靈活的，高效的，有自動機制(可能指編解碼)工具用於序列化結構數據。&lt;br /&gt;
類似 XML，但是更小、更快、更簡單。你定義你的結構化資料，然後就可以使用工具生成的特殊代碼方便的使用各種語言 (c++ python java)&lt;br /&gt;
從各種數據流中讀寫你的結構化資料。你甚至可在不打斷已經部署的程式的情況下重新更新你的資料結構（熱部署）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why not just use XML? 為什麽不使用XML?&lt;/strong&gt;&lt;br /&gt;
protocol buffer 有很多 XML 不具備的優點：&lt;br /&gt;
1.簡單；&lt;br /&gt;
2.小巧：3-10倍&lt;br /&gt;
3.效率高：20-100倍&lt;br /&gt;
4.無雙重義意&lt;br /&gt;
5.有自動工具生成&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do they work? 如何開始運作?&lt;/strong&gt;&lt;br /&gt;
你只需要安裝 google 的 protocol buffer&lt;br /&gt;
編輯 .proto 檔&lt;br /&gt;
執行 protoc &amp;ndash;cpp_out=. 檔名&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;strong&gt;Example: 範例 1&lt;/strong&gt;&lt;br /&gt;
package tutorial;&lt;br /&gt;
message Person {&lt;br /&gt;
required string name = 1;&lt;br /&gt;
required int32 id = 2;&lt;br /&gt;
optional string email = 3;&lt;/p&gt;
&lt;p&gt;enum PhoneType {&lt;br /&gt;
MOBILE = 0;&lt;br /&gt;
HOME = 1;&lt;br /&gt;
WORK = 2;&lt;br /&gt;
}&lt;br /&gt;
message PhoneNumber {&lt;br /&gt;
required string number = 1;&lt;br /&gt;
optional PhoneType type = 2 [default = HOME];&lt;br /&gt;
}&lt;br /&gt;
repeated PhoneNumber phone = 4;&lt;br /&gt;
}&lt;br /&gt;
message AddressBook {&lt;br /&gt;
repeated Person person = 1;&lt;br /&gt;
}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Three type 三種資料型態&lt;/strong&gt;&lt;br /&gt;
required：必須提供字段值，否則對應的 message 就會被認為是&amp;ldquo;未初始化的。&amp;ldquo;&lt;br /&gt;
optional：字段值指定與否都可以。如果沒有指定一個可選的字段值，它就會使用默認值。&lt;br /&gt;
repeated：字段會重複 n 次（可以為0）。重複的值的順序將被保存在緩衝區中的協議。&lt;/p&gt;
&lt;p&gt;Required 是永久性的：在把一個字段標識為 Required 的時候，你應該特別小心。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Start working 開始&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/addressbook.proto&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這會產生以下文件&lt;br /&gt;
addressbook.pb.h：聲明你生成的 class 的標頭檔。&lt;br /&gt;
addressbook.pb.cc：你生成的 class 的實作檔。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example: 範例 2&lt;/strong&gt;&lt;br /&gt;
Person person;&lt;br /&gt;
person.set_name(&amp;quot;John Doe&amp;quot;);&lt;br /&gt;
person.set_id(1234);&lt;br /&gt;
person.set_email(&amp;quot;jdoe@example.com&amp;quot;);&lt;br /&gt;
fstream output(&amp;quot;myfile&amp;quot;, ios::out | ios::binary);&lt;br /&gt;
person.SerializeToOstream(&amp;amp;output);&lt;/p&gt;
&lt;p&gt;fstream input(&amp;quot;myfile&amp;quot;, ios::in | ios::binary);&lt;br /&gt;
Person person;&lt;br /&gt;
person.ParseFromIstream(&amp;amp;input);&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;Name: &amp;quot; &amp;lt;&amp;lt; person.name() &amp;lt;&amp;lt; endl;&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;E-mail: &amp;quot; &amp;lt;&amp;lt; person.email() &amp;lt;&amp;lt; endl;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Entire message, including: 內部 API&lt;/strong&gt;&lt;br /&gt;
bool IsInitialized() const;：檢查是否全部的required字段都被設置（set）了值。&lt;br /&gt;
string DebugString() const;：返回一個可讀的訊息表示形式，對讀取特别有用。&lt;br /&gt;
void CopyFrom(const Person&amp;amp; from);：用外部訊息的值，覆寫調用者訊息内部的值。&lt;br /&gt;
void Clear();：將所有項回復到空狀態（empty state）。&lt;br /&gt;
bool SerializeToString(string* output) const;：將消息序列化並儲存在指定的字符串中。注意裡面的內容是binary 的；我們只是使用字符串作為一個很方便的容器。&lt;br /&gt;
bool ParseFromString(const string&amp;amp; data);：從给定的 string 解析訊息。&lt;br /&gt;
bool SerializeToOstream(ostream* output) const;：将訊息寫入到给定的 C++ ostream 中。&lt;br /&gt;
bool ParseFromIstream(istream* input);：從给定的 C++ istream 解析訊息。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://code.google.com/intl/zh-TW/apis/protocolbuffers/docs/overview.html&quot;&gt;http://code.google.com/intl/zh-TW/apis/protocolbuffers/docs/overview.html&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.cppprog.com/2010/0908/207_4.html&quot;&gt;http://www.cppprog.com/2010/0908/207_4.html&lt;/a&gt;&lt;/p&gt; &lt;span class=&#039;read-more&#039;&gt;&lt;a href=&quot;http://www.cellopoint.com/tw/media_resources/blogs/2011/05/Protocol_Buffers&quot;&gt;閱讀全文&lt;/a&gt;&lt;/span&gt;</description>
 <category domain="http://www.cellopoint.com/tw/taxonomy/term/14">Internet</category>
 <pubDate>Thu, 19 May 2011 10:12:35 +0800</pubDate>
 <dc:creator>Shawn Lin</dc:creator>
 <guid isPermaLink="false">466 at http://www.cellopoint.com/tw</guid>
</item>
</channel>
</rss>

