golang 提供了package bufio。bufio.NewReader()创建一个默认大小的readbuf,当然,也可以bufio.NewReaderSize。
funcNewReader(rdio.Reader)*Reader NewReaderreturnsanewReaderwhosebufferhasthedefaultsize(4096). funcNewReaderSize(rdio.Reader,sizeint)*Reader NewReaderSizereturnsanewReaderwhosebufferhasatleastthe specifiedsize.Iftheargumentio.ReaderisalreadyaReaderwithlarge enoughsize,itreturnstheunderlyingReader.
bufio
func(b*Reader)ReadByte()(cbyte,errerror) ReadBytereadsandreturnsasinglebyte.Ifnobyteisavailable,returnsanerror. func(b*Reader)ReadBytes(delimbyte)(line[]byte,errerror) ReadBytesreadsuntilthefirstoccurrenceofdelimintheinput,returningaslicecontainingthedatauptoandincludingthedelimiter. IfReadBytesencountersanerrorbeforefindingadelimiter,itreturns thedatareadbeforetheerrorandtheerroritself(oftenio.EOF). ReadBytesreturnserr!=nilifandonlyifthereturneddatadoesnot endindelim.Forsimpleuses,aScannermaybemoreconvenient. func(b*Reader)ReadString(delimbyte)(linestring,errerror) ReadStringreadsuntilthefirstoccurrenceofdelimintheinput,returningastringcontainingthedatauptoandincludingthe delimiter.IfReadStringencountersanerrorbeforefindingadelimiter,itreturnsthedatareadbeforetheerrorandtheerroritself(often io.EOF).ReadStringreturnserr!=nilifandonlyifthereturneddata doesnotendindelim.Forsimpleuses,aScannermaybemore convenient.
ReadByte这个接口,和C语言中fgetc很接近,每次读取一个字节。ReadBytes和ReadString都可以实现逐行读取,只要delim设置为'\n'.
packagemain import"fmt" import"os" import"io" import"flag" import"bufio" varnum_flag=flag.Bool("n",false,"numeachline") funcusage(){ fmt.Printf("%s%s\n",os.Args[0],"filename") } funccat(r*bufio.Reader){ i:=1 for{ //buf,err:=r.ReadBytes('\n') buf,err:=r.ReadString('\n') iferr==io.EOF{ break } if*num_flag{ fmt.Fprintf(os.Stdout,"%5d%s",i,buf) i++ }else{ fmt.Fprintf(os.Stdout,"%s",buf) } } return } funcmain(){ flag.Parse() if(flag.NArg()==0){ cat(bufio.NewReader(os.Stdin)) } fori:=0;i<flag.NArg();i++{ f,err:=os.OpenFile(flag.Arg(i),os.O_RDONLY,0660) iferr!=nil{ fmt.Fprintf(os.Stderr,"%serrreadfrom%s:%s\n",flag.Arg(0),err) continue } cat(bufio.NewReader(f)) f.Close() } }
用scaner逐行读取
funccat(scanner*bufio.Scanner)error{ forscanner.Scan(){ fmt.Println(scanner.Text()) //fmt.Fprintf(os.Stdout,"%s\n",scanner.Text()) } returnscanner.Err() }
注意,为啥执行Scan,Text()函数就能返回下一行呢?因为默认的分割函数就是ScanLines.如你有特殊的需求来分割,func (s *Scanner) Split(split SplitFunc)
这个函数可以制定SplitFunc。你可以定制自己的分割函数。
需要注意的是,Scan会将分割符号\n去除,如果Fprintf输出的话,不添加\n打印,会出现没有换行的现象,如下所示
fmt.Fprintf(os.Stdout,scanner.Text())
manu@manu-hacks:~/code/go/self$gorunmycat_v2.gotest.txt thisistestfilecreatedbygoifnotexisted,pleasecreatethisfileifexisted,Pleasewriteappendhelloworld,hellogothisistestfilecreatedbygoifnotexisted,hellogomanu@manu-hacks:~/code/go/self$cattest.txt thisistestfilecreatedbygo ifnotexisted,pleasecreatethisfile ifexisted,Pleasewriteappend helloworld,hellogo thisistestfilecreatedbygo ifnotexisted,hellogo
f,0660) ... error:=cat(bufio.NewScanner(f)) iferr!=nil{ fmt.Fprintf(os.Stderr,flag.Arg(i),error) }原文链接:https://www.f2er.com/go/190249.html