2011-09-12 64 views
2

查看標題。如何替換管道的GetFileSize()?

在命名管道的客戶端,我想確定要從命名管道讀取的內容的大小,以便爲緩衝區分配內存以獲取內容。

MSDN help說:

您不能使用GetFileSize功能與nonseeking裝置的手柄,如管道或通信設備。要確定文件類型h文件,請使用GetFileType函數。

嗯。好的。但是,如果我不能使用GetFileSize來確定從管道讀取的數據量,那麼我應該使用什麼?目前,我做

length = GetFileSize(pipehandle, 0); 
while(length == 0){ 
    Sleep(10);       // wait a bit 
    length = GetFileSize(pipehandle, 0); // and try again 
} 

遲早length得到更大的零,但等待似乎有點對我不好。


背景:我有等待客戶端來連接管服務器(大致從MSDN example多線程管道服務器)。連接後,服務器讀取文件的內容並使用管道連接將其傳遞給客戶端。


更多背景:總的原因,我想這樣做是我要與實現XML解析器外部庫工作。最初,解析器打開一個文件,然後將CreateFileMapping應用於該文件,最後調用MapViewOfFile以獲取文件內容。

現在,項目規則已經改變,我們不再允許在磁盤上創建文件,所以我們需要另一種方式將信息從App1(管道服務器)傳遞到App2(管道客戶端)。要改變儘可能少,我決定用管道傳遞,因爲在第一個視圖中的數據,打開一個管道一樣打開任何其他文件,我認爲我必須做的只有很少的改動就擺脫閱讀文件,同時能夠從管道讀取。

目前,我確定管道中的數據的大小(我知道它只用一次將輸入文件從App1傳遞到App2),然後執行malloc以獲取緩衝區並讀取整個內容進入該緩衝區的管道。

如果我在一個完全滑出了賽道,我還開放給任何建議,把事情做得更好。

+2

爲什麼你需要文件大小?有沒有一種方法可以執行與流操作相同的任務,而不是分配空間將整個文件存儲在內存中?沒有真正的方法來獲取管道的「文件大小」,因爲它沒有任何有意義的定義。一個管道繼續提供數據,直到沒有更多的數據可供使用,並且在此之前無法分辨出有多少數據。它甚至可以是無限的。 – BishopRook

+0

@BishopRook:擴展問題提供更多背景。 – eckes

回答

2

很明顯,在這種情況下你想要一個PIPE_TYPE_BYTE,因爲數據量是不可預測的。對待它就像客戶端中的常規文件一樣,使用4096字節的小緩衝區重複調用ReadFile()。如果你需要將它存儲在一個數組中,那麼你可以簡單地寫一個整數,這樣客戶端就知道該數組有多大。

+0

+1用於*先寫整數*。我會試一試。 – eckes

1

如果您在PIPE_TYPE_MESSAGE類型創建你管,你將能夠使用PeekNamedPipe方法來檢索從管道的完整信息。

PIPE_TYPE_MESSAGE和PIPE_TYPE_BYTE之間的主要區別是:

    在留言類型
  • ,系統管理送入管的值的長度,就問我讀一個消息,你會得到所有的消息(爲了避免填充所有內存,請使用不要太大的消息)
  • BYTE類型,您必須管理您發送的數據的長度。也許一個TLV protocol可能是一個很好的方法來知道你的「消息」的大小(也許T型部分聽起來像一個無用的),然後你可以閱讀的內容分爲兩部分:首先,讀取的第一個字節將給你是消息的大小,如果你不想過度填充內存,然後按部分讀消息。
+0

目前,它是'PIPE_TYPE_BINARY',因爲我無法弄清楚'PIPE_TYPE_MESSAGE'和'BINARY'對我來說聽起來更容易。主要區別是什麼? – eckes

+0

@eckes:編輯我的答案,試圖解釋我看到的主要差異。 –

+0

+1,用於清楚地指出* message *和* bype *類型之間的區別。 – eckes