2012-10-25 45 views
3

我需要找到一種方法來從io.ReadCloser對象中讀取一行,或者找到一種方法在「結束行」符號上分割一個字節數組。但是,我不知道結束符號,我找不到它。io.ReadCloser的ReadLine

我的應用程序執行php腳本,需要從腳本獲取實時輸出,並在獲取它時執行「某事」。

這裏有一小塊我的代碼:

cmd := exec.Command(prog, args) 
/* cmd := exec.Command("ls")*/ 
out, err := cmd.StdoutPipe() 
if err != nil { 
    fmt.Println(err) 
} 
err = cmd.Start() 
if err != nil { 
    fmt.Println(err) 
} 

在此之後我監視一展身手套路out緩衝區。我試過2種方法。
1)nr, er := out.Read(buf)其中buf是一個字節數組。這裏的問題是,我需要制動陣列爲每個新線
2)我的第二個選擇是創建一個新的bufio.reader
r := bufio.NewReader(out)
line,_,e := r.ReadLine()

,如果我執行命令時像ls運行良好,我得到的輸出一行一行,但如果我執行一個PHP腳本,它立即得到一個文件結束錯誤並退出(我猜這是因爲從PHP延遲輸出)

編輯:我的問題是我創建了bufio。閱讀器裏面的去例程,而如果我這樣做後StdoutPipe()像minikomi建議,它工作正常

+0

還檢查出exec.Wait,它將阻塞,直到進程退出。 – minikomi

+1

@minikomi它在我的代碼中,它只是與我無關,將它包含在示例中,但感謝提示 – Flame

回答

6

您可以創建一個使用閱讀器BUFIO,然後讀出來,直到下一個換行符(注,單引號表示字符!):

stdout, err := cmd.StdoutPipe() 
rd := bufio.NewReader(stdout) 
if err := cmd.Start(); err != nil { 
    log.Fatal("Buffer Error:", err) 
} 

for { 
    str, err := rd.ReadString('\n') 
    if err != nil { 
     log.Fatal("Read Error:", err) 
     return 
    } 
    fmt.Println(str) 
} 

如果你想從讀者在閱讀的goroutine有什麼可以阻止腳本它會退出。