2010-10-05 177 views
6

如何從C++/Qt Linux應用程序中逐行讀取FIFO /命名管道?如何從C++/Qt Linux應用程序中逐行讀取FIFO /命名管道?

今天我可以打開並從一個Qt程序的前端讀取, 但我不能讓程序逐行讀取數據。 Qt讀取整個文件,這意味着他等待直到「發件人」關閉他的會話。

讓我們以一些shell命令爲例來展示我想要的應用程序。

首先創建一個FIFO

mkfifo MyPipe 

然後我們可以使用cat從FIFO

cat MyPipe 

然後我們與另一隻貓發送一些數據讀取

cat > MyPipe 

而且然後開始輸入一些東西,每次你輸入它就會到達讀者。 然後當你用Ctrl + D關閉它時,雙方都結束。

現在發件人很容易創建一個QTextStream, 你只需要刷新,當你想發送。

QFile file("MyPipe"); 
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) 
    return; 

QTextStream out(&file); 
for(int i=0; i<3; i++) { 
    out << "Hello...: " << i << "\n"; 
    out.flush(); 
    sleep(2); 
} 

file.close(); 

但隨後寫一個小讀者通過讀取線線是我現在很卡, 我所有的嘗試與Qt的LIB與最終我得到的數據,但 直到發件人在fifo上使用file.close()。 不是當他沖洗時,就像我用貓讀書時發生的那樣。

像這個例子:

QFile file("MyPipe"); 
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) 
    return 0; 

QTextStream in(&file); 
QString line; 
do { 
    line = in.readLine(); 
    qDebug() << line; 
} while (!in.atEnd()); 


file.close(); 

我缺少什麼?

它只是感覺就像我需要使用某種類型的isReady或lineAvailable對 流或類似的東西, 但我無法找到適合的文檔什麼...

/感謝


如果我去的低C級的風格,在我做 時讀取一個字符獲取其風格林海衝刺。 但能夠做到相同的Qt風格會很好。

FILE *fp; 
fp=fopen("MyPipe", "r"); 
char c; 
while((c=getc(fp)) != EOF) 
{ 
    printf("%c",c); 
} 
fclose(fp); 

更新

當我開始調試程序掛在的readLine(), 不要繼續下去,直到對方關閉FIFO。

和我做同樣的使用得到「>>」

line = in.readLine(); 
    in >> line; 
+1

難道是管道正在被立即讀取,它實際上是被緩衝的屏幕輸出?你用過'qDebug()<< line;',我沒有看到任何沖洗。 – 2010-10-30 20:54:20

+0

好點,沒想到那個。 – Johan 2010-10-31 07:41:08

回答

4

使用低級c風格並讀取一個字符。

FILE *fp; 
fp=fopen("MyPipe", "r"); 
char c; 
while((c=getc(fp)) != EOF) 
{ 
    printf("%c",c); 
} 
fclose(fp); 
+0

'c'必須是'int',否則它可能是一個無限循環如果'char'是無符號的('EOF'是負整數通常情況下爲'-1') – jfs 2013-11-24 08:20:38

2

我不知道有什麼不工作,但你可以嘗試使用strace的調試它:

strace -o writer.log -e trace=write ./writer 
strace -o reader.log -e trace=read ./reader 

第一行將記錄您的編寫器程序所做的所有寫入系統調用。第二行以類似的方式工作。 這樣你可以跟蹤系統調用,並確保你的沖洗工作。

如果你看到重複的調用讀取,有正確的時間和數據,那麼你有QTextStream的問題。

如果你不使用QTextStream,但直接從文件中讀取會發生什麼?

+0

strace很好,我在另一個窗口中開始了「watch tail reader.log」,我可以看到他確實獲得了我發給他的數據。 – Johan 2010-10-05 11:19:24

+0

@Johan:你確定問題出在讀者身上嗎? – shodanex 2010-10-06 11:34:08

+0

95%肯定,因爲如果我用「C版本」替換它的工作,「Qt版本」。 – Johan 2010-10-06 12:34:51

1

您可以嘗試用QIODevice::Unbuffered標誌打開閱讀器端的文件。

+1

上帝的主意,但它仍然是一樣的:( – Johan 2010-10-05 17:05:24

2
if(file.bytesAvailable()) 
QString line = file.readLine(); 

你可以使用這樣的事情。

+0

對於特殊文件(包括命名管道),QFile實現的bytesAvailable不起作用,事實上使應用程序崩潰! – 2016-06-09 13:20:09