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


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

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

    ------注:文件末尾的最后一个字符并不是文件描述符,其实就是一个简单的' ',一般用"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
    ", file, err)
    		return
    	}
    
    	for {
    		n, err := f.Read(buf)
    		if err != nil && err != io.EOF {
    			fmt.Printf("read file %s failed: %v
    ", 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
    ", 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
    ", string(log))
    	}
    }
    

      

      

  • 相关阅读:
    二线城市的创业人才之战
    小程序的风口到底如何?
    短视频广告一条上百万,揭秘短视频背后的故事
    让我们来看看这些企业的创始人,在互联网金融的十年里的故事
    背靠大树成为创业成功的显学
    草根站长的艰辛创业路
    互联网大佬们的创业重要选择时刻
    80后的罗敏已经在创业路上走了十几年
    CentOS7 通过 YUM 升级 VIM8
    matplotlib 画图中的basemap安装问题
  • 原文地址:https://www.cnblogs.com/YaoDD/p/5691558.html
Copyright © 2020-2023  润新知