思路
- 通过Seek函数从末尾移动游标然后每次读取一个字节
- 判断是否为换行符
- 换行符,新起一个逆序buff,新建字符串
- 非换行符,加入缓冲buff
- 直到文档开头,或限制行数。
实现
import (
"fmt"
"io"
"os"
)
func main() {
f, err := os.Open("readend/test.log")
if err != nil {
panic(fmt.Sprintf("open file error:%s", err.Error()))
}
defer f.Close();
buff := make([]byte, 0, 4096)
char := make([]byte, 1)
stat, _ := f.Stat()
filesize := stat.Size()
var cursor int64 = 0
cnt := 0
for {
cursor -= 1
_, _ = f.Seek(cursor, io.SeekEnd)
_, err = f.Read(char)
if err != nil {
panic(err)
}
if char[0] == '\n' {
if len(buff) > 0 {
revers(buff)
fmt.Println(string(buff))
cnt++
if cnt == 300 {
break
}
}
buff = buff[:0]
} else {
buff = append(buff, char[0])
}
if cursor == -filesize {
break
}
}
}
func revers(s []byte) {
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}
}
参考文献
[1]. stackoverflow . How to Read last lines from a big file with Go every 10 secs . Bactisme . 2018.07 . https://stackoverflow.com/questions/17863821/how-to-read-last-lines-from-a-big-file-with-go-every-10-secs