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

deepdata · · 2707 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

主要用于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 )

}

}


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:1006366459

2707 次点击  
加入收藏 微博
1 回复  |  直到 2000-01-01 00:00:00
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传