Golang中使用ioutil读取文件时遇到的问题

Golang中使用ioutil读取文件时遇到的问题 你好!😊 我是Go语言的新手(大约学习一周左右),但有一些C++经验。

我正在尝试编写一个能够持续读取被不断写入的文件的代码。 它的工作原理是先将文本文件的行数写入一个整数(通过CountLogLines函数) 下次读取文件时,它应该将每个新增的单独行保存到字符串切片中, 然后重新设置行数。 这样之后我就可以访问从函数返回的切片,并单独处理每一新行。

但不知为何我的代码无法正常工作… 它要么没有任何输出,要么会跳过某些行。 能帮帮我吗? 谢谢!🙂

文本文件的写入格式如下:

\n
\r \n
Some_String\n
\n
\r \n
Some_String\n
func countLogLines() int {
	f, err := ioutil.ReadFile(logFileLocation)
	if err != nil {
		log.Fatalf("countLogLines: ioutil.ReadFile() Error: %v", err)
	}
	str := strings.Split(string(f), "\n")
	return len(str)
}

func readLog() []string {
	f, err := ioutil.ReadFile(logFileLocation)
	if err != nil {
		log.Fatalf("readLogFile: ioutil.ReadFile() Error: %v", err)
	}
	str := strings.Split(string(f), "\n")
	if loglen < len(str) {
		var strout []string
		i := 1
		for i+loglen <= len(str) {
			strout = append(strout, str[i+loglen])
		}
		loglen = len(str)
		return strout
	}
	return nil
}

更多关于Golang中使用ioutil读取文件时遇到的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

哎呀…
我只是因为大量编码而超级疲惫 😅
事实证明,在休息一段时间后,我不到30分钟就解决了问题。
抱歉过早发帖了 😐
我要关闭这个主题了 ^^

更多关于Golang中使用ioutil读取文件时遇到的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在您的代码中,有几个关键问题导致了行读取不完整或跳过某些行的情况。主要问题在于循环逻辑和索引处理。

以下是修复后的代码:

func readLog() []string {
    f, err := ioutil.ReadFile(logFileLocation)
    if err != nil {
        log.Fatalf("readLogFile: ioutil.ReadFile() Error: %v", err)
    }
    
    str := strings.Split(string(f), "\n")
    
    if loglen < len(str) {
        var strout []string
        // 从当前记录的行数开始,到文件末尾
        for i := loglen; i < len(str); i++ {
            // 跳过空行
            if strings.TrimSpace(str[i]) != "" {
                strout = append(strout, str[i])
            }
        }
        loglen = len(str)
        return strout
    }
    return nil
}

主要修复点:

  1. 循环逻辑:原代码中的 i := 1i+loglen <= len(str) 会导致索引计算错误。应该直接从 loglen 开始遍历到文件末尾。

  2. 无限循环:原代码在循环中没有递增 i,会导致无限循环。

  3. 空行处理:根据您描述的文件格式包含 \n\r \n 等,添加了空行过滤逻辑。

  4. 索引修正:原代码 str[i+loglen] 会导致数组越界,正确的索引应该是 str[i]

使用示例:

var loglen int

func main() {
    // 初始化行数
    loglen = countLogLines()
    
    for {
        newLines := readLog()
        if newLines != nil {
            for _, line := range newLines {
                fmt.Printf("新行: %s\n", line)
                // 处理每一行
            }
        }
        time.Sleep(1 * time.Second) // 间隔检查
    }
}

注意:由于您使用了 ioutil.ReadFile 一次性读取整个文件,在处理大文件或高频写入时可能会有性能问题。对于持续监控文件变化的场景,建议考虑使用 bufio.Scannerfsnotify 包来优化。

回到顶部