Go實現(xiàn)將io.Writer轉換成字符串
假設我們需要在Go中運行下面的命令:
PS -A | grep wget
這里需要寫成兩個exec.Command
,如下,第一個命令為cmd
,第二個為cmd2
:
cmd := exec.Command("PS", "-A") cmd2 := exec.Command("grep", "wget")
然后使用管道連接二者的標準輸出和標準輸入,需要注意第一個命令cmd
的標準輸出應該使用cmd.StdoutPipe()
,而不是Stdout
,如下(忽略了錯誤err
和其處理):
cmd2.Stdin, _ = cmd.StdoutPipe()
因為cmd.Stdout
是一個io.Writer
,是一個寫入器,因為這個輸出是要寫入某些地方的。而同理,cmd2.Stdin
是一個io.Reader
,是一個讀取器,用來讀取一些地方的內容。二者直接賦值的話會出現(xiàn)類型不匹配的錯誤。所以需要使用StdoutPipe()
函數,這個函數會返回一個io.Reader
。(這里比較繞,所以可能需要想一下)
在獲取了輸出之后,需要將其轉換成字符串的話,可以使用bytes.Buffer
來獲取cmd2.Stdout
的標準輸出(記住這是個io.Writer
),然后再轉換成字符串。
我們是是無法直接將io.Writer
直接寫入到bytes.Buffer
之中的,你可能會說bytes.Buffer
不是有兩個方法ReadFrom
和WriteTo
嗎?
前者只能讀取io.Reader
的,后者只能寫入io.Writer
,所以我們需要一個管道來將io.Writer
轉換成io.Reader
,然后才能讀取或復制其內容。而這個轉換就是再使用一次管道,如下:
var buf bytes.Buffer r, w, _ := os.Pipe() cmd2.Stdout = w go buf.ReadFrom(r)
這里buf.ReadFrom(r)
必須使用 goroutine,也就是讓這個代碼并行運行,所以在前面加上go
。
這里的
go buf.ReadFrom(r)
也可以使用go io.Copy(&buf, r)
替代,效果一樣。
因為命令執(zhí)行的順序是先啟動cmd2
,然后運行cmd
,cmd
運行完之后,數據流通過管道傳遞給cmd2
,cmd2
再運行。不然cmd
運行的時候的標準輸出是空的,就會一直等。
buf.ReadFrom(r)
對cmd2
也是同理,不過由于這是行代碼,無法使用start
啟動它,所以并行就行了。
接下來的命令如下:
cmd2.Start() cmd.Run() cmd2.Wait()
這里就是前面說的流程:cmd2
啟動,運行cmd
,讓cmd2
等待cmd
的輸出。
需要注意一點:go buf.ReadFrom(r)
其實可以放在上面代碼中,除了最后一行之外的任何地方。之所以不能放在最后是因為這時候都運行完了,再讀取就是空的了。
然后將其轉換成字符串:
str := buf.String()
打印看看:
fmt.Println("123" + str + "123")
之所以要前后都加上"123"
是為了避免調試的時候把輸出到標準輸出文件的內容當成這里打印的。
結果如下:
% go run main.go
12360651 ttys010 0:00.00 grep wget
123
這里分成兩行是因為獲取的時候grep wget
后面有個\n
,這里看不出來,如果%#v
格式化打印就能看到了。
完整代碼如下:
func main() { cmd := exec.Command("PS", "-A") cmd2 := exec.Command("grep", "wget") cmd2.Stdin, _ = cmd.StdoutPipe() var buf bytes.Buffer r, w, _ := os.Pipe() cmd2.Stdout = w // 下面這行代碼可以替換為:go io.Copy(&buf, r) go buf.ReadFrom(r) cmd2.Start() cmd.Run() cmd2.Wait() str := buf.String() fmt.Println("123" + str + "123") }
到此這篇關于Go實現(xiàn)將io.Writer轉換成字符串的文章就介紹到這了,更多相關Go io.Writer轉換成字符串內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Golang實現(xiàn)帶優(yōu)先級的select
這篇文章主要為大家詳細介紹了如何在Golang中實現(xiàn)帶優(yōu)先級的select,文中的示例代碼講解詳細,對我們學習Golang有一定的幫助,需要的可以參考一下2023-04-04Go1.21新增內置函數(built-in?functions)詳解
Go?1.21新增的內置函數分別是?min、max?和?clear,這篇文章主要帶大家一起了解一下這幾個函數的用途和使用示例,感興趣的小伙伴可以學習一下2023-08-08