Go实现将io.Writer转换成字符串

 更新时间:2024年05月05日 10:23:44   作者:zhonguncle  
golang中提供了各种类型之间的转换方法,其中,将其他类型转换为字符串类型是常见的操作,本文主要介绍了Go实现将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,是一个读取器,用来读取一些地方的内容。二者直接赋值的话会出现类型不匹配的错误。所以需要使用StdoutPipe()函数,这个函数会返回一个io.Reader。(这里比较绕,所以可能需要想一下)

在获取了输出之后,需要将其转换成字符串的话,可以使用bytes.Buffer来获取cmd2.Stdout的标准输出(记住这是个io.Writer),然后再转换成字符串。

我们是是无法直接将io.Writer直接写入到bytes.Buffer之中的,你可能会说bytes.Buffer不是有两个方法ReadFromWriteTo吗?

前者只能读取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)替代,效果一样。

因为命令执行的顺序是先启动cmd2,然后运行cmdcmd运行完之后,数据流通过管道传递给cmd2cmd2再运行。不然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实现将io.Writer转换成字符串的文章就介绍到这了,更多相关Go io.Writer转换成字符串内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Golang中println和fmt.Println区别解析

    Golang中println和fmt.Println区别解析

    Golang 中打印数据通常使用 fmt.Println() 方法,也可以使用内置的 println() 方法。这两个方法大家可能都使用过,它们的区别是什么呢?本文给大家详细讲解,感兴趣的朋友跟随小编一起看看吧
    2023-03-03
  • 浅析golang如何在多线程中避免CPU指令重排

    浅析golang如何在多线程中避免CPU指令重排

    这篇文章主要为大家详细介绍了golang在多线程中避免CPU指令重排的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-03-03
  • Go语言操作MySQL的知识总结

    Go语言操作MySQL的知识总结

    Go语言中的database/sql包提供了保证SQL或类SQL数据库的泛用接口,并不提供具体的数据库驱动。本文介绍了Go语言操作MySQL的相关知识,感兴趣的可以了解一下
    2022-11-11
  • 深入探讨Golang中如何进行并发发送HTTP请求

    深入探讨Golang中如何进行并发发送HTTP请求

    在 Golang 领域,并发发送 HTTP 请求是优化 Web 应用程序的一项重要技能,本文探讨了实现此目的的各种方法,文中的示例代码讲解详细,希望对大家有所帮助
    2024-01-01
  • 使用Golang轻松实现JWT身份验证的示例代码

    使用Golang轻松实现JWT身份验证的示例代码

    JSON Web Tokens (JWT)是一种流行的安全方法,用于在两个方之间表示声明,本文主要为大家详细介绍了实现Go应用程序中的JWT身份验证过程,需要的可以参考下
    2024-02-02
  • Go语言编译环境设置教程

    Go语言编译环境设置教程

    Go语言支持高并发(goroutine)、自动垃圾回收,编译为跨平台二进制文件,云原生兼容且社区活跃,开发便捷,内置测试与vet工具辅助检测错误,依赖模块化管理,提升开发效率
    2025-07-07
  • 浅析Go语言中内存泄漏的原因与解决方法

    浅析Go语言中内存泄漏的原因与解决方法

    这篇文章主要来和大家聊一聊Go语言中内存泄漏的那些事,例如内存泄漏的原因与解决方法,文中的示例代码讲解详细,需要的小伙伴可以参考下
    2024-02-02
  • 详解Go语言中的Slice链式操作

    详解Go语言中的Slice链式操作

    这篇文章主要为大家详细介绍了Go语言中的Slice链式操作的相关知识,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以了解一下
    2023-04-04
  • Go中的nil切片和空切片区别详解

    Go中的nil切片和空切片区别详解

    这篇文章主要介绍了Go中的nil切片和空切片区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • go语言题解LeetCode1128等价多米诺骨牌对的数量

    go语言题解LeetCode1128等价多米诺骨牌对的数量

    这篇文章主要为大家介绍了go语言题解LeetCode1128等价多米诺骨牌对的数量示例详解,
    2022-12-12

最新评论