轉載自:http://blog.csdn.net/morewindows/article/details/7390441web
計算機中管道pipe相似於現實世界中的水管道,在一端放入水流,另外一端就會流出來。在計算機機中水流天然被數據流所代替了。計算機中管道分爲匿名管道和命名管道,本篇將主要介紹用匿名管道來完成這一重定向輸出任務,命名管道就留給下一篇來介紹了。windows
先來看看如何建立和使用匿名管道。安全
第一個 CreatePipeapp
函數功能:建立管道異步
函數原型:ide
BOOLWINAPICreatePipe(函數
PHANDLEhReadPipe,oop
PHANDLEhWritePipe,this
LPSECURITY_ATTRIBUTESlpPipeAttributes,編碼
DWORDnSize
);
函數說明:
第一個參數返回新建立的管道的讀取端句柄。
第二個參數返回新建立的管道的寫入端句柄。
注意不能在管道的讀取端寫入數據也不能在寫入端讀取數據。
第三個參數表示管道的安全屬性,一般能夠做以下設置:
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
第四個參數表示管道的緩衝區容量,爲0表示使用默認大小。
函數執行成功返回TRUE,不然返回FALSE。
第二個 ReadFile
函數功能:從管道中讀取數據
函數原型:
BOOLReadFile(
HANDLEhFile,
LPVOIDlpBuffer,
DWORDnNumberOfBytesToRead,
LPDWORDlpNumberOfBytesRead,
LPOVERLAPPEDlpOverlapped
);
函數說明:
第一個參數爲句柄,能夠是建立文件函數CreateFile()的返回值也能夠是管道。
第二個參數是一個指向緩衝區的指針,函數將讀取的數據寫入該緩衝區。
第三個參數的表達很是好,光從名字上就能夠知道這是用來指定讀取的字節數。
第四個參數將返回實際讀取到的字節數。
第五個參數是用於異步操做方面,通常傳入NULL便可。
第三個 WriteFile
函數功能:向管道寫入數據
函數原型:
BOOLWriteFile(
HANDLEhFile,
LPCVOIDlpBuffer,
DWORDnNumberOfBytesToWrite,
LPDWORDlpNumberOfBytesWritten,
LPOVERLAPPEDlpOverlapped
);
函數說明:
第一個參數爲句柄,能夠是建立文件函數CreateFile()的返回值也能夠是管道。
第二個參數是一個指針,該指針指向待寫入管道的數據。
第三個參數表示要寫入的字節數。
第四個參數將返回實際寫入管道的字節數。
第五個參數是用於異步操做方面,通常傳入NULL便可。
第四個CloseHandle
函數功能:關閉管道的一端
函數原型:BOOLCloseHandle(HANDLEhObject);
函數說明:當讀取和寫入端都關閉後,系統會關閉管道並回收資源。
從後面三個函數能夠看出,向管道中讀取和寫入數據就和向文件中讀取和寫入數據是同樣的(事實上管道也是一種特殊的文件——內存映射文件)。
使用管道要注意的一個地方是:讀取和寫入數據時,必定要注意順序,MSDN上說,若是管道中沒有數據,調用ReadFile()會形成阻塞,直到有其它線程將數據寫入管道。一樣,當有線程正在管道中讀取數據時,其它試圖將數據寫入管道的的線程也會被阻塞。
所以對上一篇的示例程序進行重定向時,能夠先建立二個管道,一個用來存放輸入數據,稱爲數據輸入管道,另外一個用來存放輸出數據,稱爲數據輸出管道。而後從輸入文件中讀取數據並寫入數據輸入管道。再啓動示例程序做爲子進程,子進程的輸入輸出已經改爲從數據輸入管道中讀取和輸出到數據輸出管道。子進程運行結束後,從數據輸出管道中將數據寫入到輸出文件便可。整個流程圖以下所示:
下面給出使用管道的示例代碼:
運行結果以下圖:
結果徹底正確,說明咱們的程序已經完成了啓動其它程序並對它進行重定向這一功能。
對匿名管道總結一下:匿名管道有讀取端和寫入端。匿名管道建立(CreatePipe)後就能夠像讀寫文件同樣的對管道中的數據讀寫(ReadFile與WriteFile),但要注意讀寫順序。匿名管道在關閉兩端後會由系統銷燬並回收資源。
匿名管道的使用比較常見,下面是二個安裝程序的截圖。
QQ遊戲的安裝過程截圖:
五筆編碼及時查的安裝過程截圖:
對比下這二個截圖,顯示的內容都差很少,都是解壓縮文件並移動到指定地方。惟一不一樣的是一個是控制檯界面,另外一個是圖形界面。聯想上面的程序,不可貴知QQ遊戲的安裝實際也是使用管道將一個控制檯程序的輸出內容顯示到圖形界面,這樣既美觀又便於維護。