Golang语言实现 tail 查看文本文件末行功能,类似于linux tail -n 100 功能

时间:2022-05-04
本文章向大家介绍Golang语言实现 tail 查看文本文件末行功能,类似于linux tail -n 100 功能,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
主要用于Web服务日志最新行查看。
package main
import(
  "fmt"
  "os"
  "bytes"
)
const (
  defaultBufSize = 4096
)
func tail( filename string, n int ) (lines []string,err error) {
  f,e := os.Stat( filename )
  if e == nil {
    size := f.Size()
    var fi *os.File
    fi,err = os.Open(filename) 
    if err == nil{ 
      b := make( []byte,defaultBufSize )
      sz := int64(defaultBufSize)
      nn := n
      bTail := bytes.NewBuffer([]byte{})
      istart := size
      flag := true
      for flag {
        if istart < defaultBufSize {
          sz = istart
          istart = 0
          //flag = false
        }else{
          istart -= sz
        }
        _,err = fi.Seek( istart,os.SEEK_SET )
        if err==nil {
          mm,e := fi.Read( b )
          if e==nil && mm>0 {
            j := mm
            for i:=mm-1;i>=0;i-- {
              if b[i]=='n' {
                bLine := bytes.NewBuffer([]byte{})
                bLine.Write( b[i+1:j] )
                j = i
                if bTail.Len()>0 {
                  bLine.Write( bTail.Bytes() )
                  bTail.Reset()
                }

                if (nn==n && bLine.Len()>0) || nn<n {	//skip last "n"
                  lines = append( lines,bLine.String() )
                  nn --
                }
                if nn==0 {
                  flag = false
                  break
                }
              }
            }
            if flag && j>0 {
              if istart==0 {
                bLine := bytes.NewBuffer([]byte{})
                bLine.Write( b[:j] )
                if bTail.Len()>0 {
                  bLine.Write( bTail.Bytes() )
                  bTail.Reset()
                }
                lines = append( lines,bLine.String() )
                flag = false
              }else{
                bb := make( []byte,bTail.Len() )
                copy( bb,bTail.Bytes() )
                bTail.Reset()
                bTail.Write( b[:j] )
                bTail.Write( bb )
              }
            }
          }
        }
      }
      //func (f *File) Seek(offset int64, whence int) (ret int64, err error)
       //func (f *File) Read(b []byte) (n int, err error) {
    } 
    defer fi.Close()
  } 
  return
}
func main(){
  lns,_ := tail("此处为日志文件路径",50)  //查看文件末行
 for _,v := range lns {
   fmt.Println( v )
}
}