Golang 实现简单的滚动读取文本更新

本文介绍两种使用Go语言实现实时监控文件变化的方法。一种是通过循环读取文件并处理文件结束标识,另一种是实现io.Reader接口配合bufio库进行高效读取。这两种方法均可实现在文件内容发生变化时立即获取新增内容。

      这个小程序要实现的效果,简单地说,就是将目标文件的内容读取输出到终端,并且目标文件并不是静态的,而是随时会添加新的内容。我们的目标就是一旦目标文件添加了新的内容,就把它读取出来并且显示到终端上。

     实现方法很简单,用一个变量offset标记已经读到了文件的哪个位置,每次循环开始前就将读指针指到相应位置。这里有两个tricky的地方需要注意,我们在每次循环的时候都要重复地打开和关闭文件,否则文件有更新也读不出来。当我们读到文件末尾时,会多读出一个字符(文件结束标识符?)。具体的实现如下:

------注:文件末尾的最后一个字符并不是文件描述符,其实就是一个简单的'\n',一般用"echo"命令或者"vim"编写文件时,就会在末尾自动添加。

 

方法一:独立实现

package main

import (
	"fmt"
	"io"
	"os"
	"time"
)

func main() {
	file := os.Args[1]
	buf := make([]byte, 1024)
	offset := 0

	f, err := os.Open(file)
	defer f.Close()
	if err != nil {
		fmt.Printf("open file %s failed: %v\n", file, err)
		return
	}

	for {
		n, err := f.Read(buf)
		if err != nil && err != io.EOF {
			fmt.Printf("read file %s failed: %v\n", file, err)
			return
		}
		if n > 1 {
			if n != len(buf) {
				n--
			}
			fmt.Printf("%s", string(buf[:n]))
			offset += n
		}

		if n != len(buf) {
			time.Sleep(1 * time.Second)
			f.Close()
			f, err = os.Open(file)
			if err != nil {
				fmt.Printf("open file %s failed: %v\n", file, err)
				return
			}
			f.Seek(int64(offset), 0)
		}
	}

}

  

方法二:实现io.Reader接口,装饰bufio库

package main

import (
	"os"
	"bufio"
	"time"
	"io"
	"fmt"
)

type fileReader struct {
	file	string
	offset	int64
}

func (f *fileReader) Read(p []byte)  (n int, err error) {
	reader, err := os.Open(f.file)
	defer reader.Close()
	if err != nil {
		return 0, err
	}
	reader.Seek(f.offset, 0)

	n, err = reader.Read(p)

	if err == io.EOF {
		time.Sleep(1 * time.Second)
	}
	f.offset += int64(n)
	
	return n, err
}

func main() {
	file := &fileReader{os.Args[1], 0}
	br := bufio.NewReader(file)
	
	for {
		log, _, err := br.ReadLine()

		if err == io.EOF {
			continue
		}

		if err != nil {
			fmt.Printf("err: %v", err)
			return
		}

		fmt.Printf("%s\n", string(log))
	}
}

  

  

转载于:https://www.cnblogs.com/YaoDD/p/5691558.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值