为了账号安全,请及时绑定邮箱和手机立即绑定

golang写大文件的疑问

golang写大文件的疑问

慕村9548890 2019-04-09 20:23:47
写了个小程序,批量ssh远端服务器操作,并且将结果保存到本地.现在使用的方法:使用exec.Command执行命令,获取cmd.Stdout,并且结果outf.WriteString到文件.如果场景变成是grep一个比较大的日志,有比较大的标准输出,这个时候是全部都读取到内存再一次性写到文件中么?是否有办法可以进行优化?谢谢.
查看完整描述

2 回答

?
翻阅古今

TA贡献1780条经验 获得超5个赞

多谢huandu和felix,使用os/exec就可以处理所有的内容了.
Packageexecrunsexternalcommands.Itwrapsos.StartProcesstomakeiteasiertoremapstdinandstdout,connectI/Owithpipes,anddootheradjustments.
packagemain
import(
"fmt"
"io"
"log"
"os"
"os/exec"
)
funccheckError(errerror){
iferr!=nil{
log.Fatalf("Error:%s",err)
}
}
funcmain(){
//Replace`ls`(anditsarguments)withsomethingmoreinteresting
cmd:=exec.Command("ssh","1.1.1.1","find/")
//Createstdout,stderrstreamsoftypeio.Reader
stdout,err:=cmd.StdoutPipe()
checkError(err)
stderr,err:=cmd.StderrPipe()
checkError(err)
//Startcommand
err=cmd.Start()
checkError(err)
//Don'tletmain()exitbeforeourcommandhasfinishedrunning
defercmd.Wait()//Doesn'tblock
//Non-blockinglyechocommandoutputtoterminal
goio.Copy(os.Stdout,stdout)
goio.Copy(os.Stderr,stderr)
//IloveGo'strivialconcurrency:-D
fmt.Printf("Dootherstuffhere!Noneedtowait.\n\n")
}
                            
查看完整回答
反对 回复 2019-04-09
?
MYYA

TA贡献1868条经验 获得超4个赞

解决此类问题最好在远端做事情,尽可能的让远端直接处理输入,将处理过且精简了的输出通过ssh传回来。
在远端,为了尽量不在内存中载入全部文件,也应该尽量使用管道的方式逐行处理,或者直接打开文件句柄进行操作。
如果不方便在远端装可执行代码,可以考虑每次在先将处理程序通过ssh传过去。
P.S.如果仅仅是想做类似grep这种逐行处理的操作,那么直接读stdout也未尝不可,立即读立即处理,这样并不会造成太多的内存消耗。
此外,exec.Command不知道内部实现如何,很可能会一次读取所有内容到内存。一个稳妥的做法是使用os.StartProcess来执行ssh,它的最后一个参数可以用来重定向命令的stdout,详见文档。
                            
查看完整回答
反对 回复 2019-04-09
  • 2 回答
  • 0 关注
  • 374 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信