2016-03-14 40 views
1

我使用Lukas Thomsen's命名管道示例在C++中創建管道服務器並使用Java中的讀取器。命名管道在連接時檢查它是否存在於Java中

在Java方面,我想等到命名管道由C++服務器創建。

File file = new File("\\\\.\\pipe\\Pipe"); 

while(!file.exists()); 

InputStream input = new FileInputStream(file); 

然而,file.exists()以某種方式連接命名管道和實例的FileInputStream拋出以下異常:

java.io.FileNotFoundException: \\.\pipe\Pipe (All pipe instances are busy) 
at java.io.FileInputStream.open0(Native Method) 
at java.io.FileInputStream.open(Unknown Source) 
at java.io.FileInputStream.<init>(Unknown Source) 

這裏是C的片段++服務器:

int main(void) 
{ 
HANDLE hPipe; 
char buffer[1024]; 
DWORD dwRead; 


hPipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\Pipe"), 
         PIPE_ACCESS_DUPLEX | PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, // FILE_FLAG_FIRST_PIPE_INSTANCE is not needed but forces CreateNamedPipe(..) to fail if the pipe already exists... 
         PIPE_WAIT, 
         1, 
         1024 * 16, 
         1024 * 16, 
         NMPWAIT_USE_DEFAULT_WAIT, 
         NULL); 
while (hPipe != INVALID_HANDLE_VALUE) 
{ 
    if (ConnectNamedPipe(hPipe, NULL) != FALSE) // wait for someone to connect to the pipe 
    {    
     cout<<"connected"; 
     //do amazing stuff after being connected. 
    } 

    DisconnectNamedPipe(hPipe); 
} 

return 0; 
} 

所以在Java中等待命名管道而不拋出這個錯誤的正確方法是什麼?

+0

http://stackoverflow.com/q/的可能的複製634564/2670892 –

+0

沒有。該網站只談到從java打開管道很簡單。我需要等待,並檢查它是否已經創建之前打開它。 – 2c00L

回答

0

發生此問題的原因是,Windows上的File.exists()是使用對CreateFile,GetFileInformationByHandleCloseHandle的本地函數調用序列實現的。請參閱getFileInformation function in the Java source code。從命名管道的角度來看,這是不好的,因爲在Windows上,命名管道必須在使用和調用之間重置,因爲本地函數會作爲用途。

解決方法是在Java端打開命名管道時請求原諒而不是權限。沿着線的東西:

File file = new File("\\\\.\\pipe\\Pipe"); 

while (true) { 
    try { 
     return new FileInputStream(file); 
    } catch (IOException e) { 
     Thread.sleep(20); 
    } 
} 

(顯然,你可能不希望在實踐中永遠的循環,但在問題的代碼一樣。)

相關問題