为了账号安全,请及时绑定邮箱和手机立即绑定

在go中缓冲读取写入同一文件

在go中缓冲读取写入同一文件

Go
互换的青春 2023-08-14 16:35:10
我正在尝试逐行读取一个非常大的文件,然后替换行中的某些内容并写回同一个文件。我找不到办法做到这一点。目前我已经创建了一个临时文件并将替换的行保存在临时文件中,最后将临时文件内容复制到原始文件中。但我必须进行两次读取和两次写入。我想避免这种情况。有任何想法吗。以下是我尝试过的:file, _ := os.Open("somelargesay1GbFile.txt")defer file.Close()outFile, _ := os.OpenFile("temp.txt", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0777)defer outFile.Close()reader := bufio.NewReaderSize(file, 10*1024)for {    bytesread, isprefix, err := reader.ReadLine()    if err != nil {        if err == io.EOF {            data := changeTheData(string(bytesread))            outFile.WriteString(data)            if !isprefix {                outFile.WriteString("\r\n")            }        } else {            log.Fatal(err)        }        break    }    data := changeTheData(string(bytesread))    outFile.WriteString(data)    if !isprefix {        outFile.WriteString("\r\n")    }}最后我删除该文件somelargesay1GbFile.txt并将其重命名为temp.txt
查看完整描述

1 回答

?
临摹微笑

TA贡献1982条经验 获得超2个赞

解决方案是打开文件两次,第一次用于读取,第二次用于覆盖内容。


请参阅下面的代码。


请注意,我使用reader.ReadString('\n')而不是ReadLine. 另请注意,我在测试错误之前写入输出。这是因为最后一行不以“\n”结尾的行与错误一起返回io.EOF。


func main() {

    inFile, _ := os.Open("file.txt")

    defer inFile.Close()


    outFile, _ := os.OpenFile("file.txt", os.O_RDWR, 0777)

    defer outFile.Close()


    reader := bufio.NewReaderSize(inFile, 10*1024)


    for {

        line, err := reader.ReadString('\n')

        outFile.WriteString(changeData(line))

        if err != nil {

            if err != io.EOF {

                fmt.Println("error:", err)

            }

            break

        }

    }

}

我用这个函数测试了代码changeData,将小写字母更改为大写字母,将大写字母更改为小写字母。然后我们可以通过重复调用函数来测试更改。


func changeData(data string) string {

    o := make([]rune, 0, len(data))

    for _, r := range data {

        if unicode.IsLetter(r) {

            if unicode.IsUpper(r) {

                o = append(o, unicode.ToLower(r))

            } else {

                o = append(o, unicode.ToUpper(r))

            }

        } else {

            o = append(o, r)

        }

    }

    return string(o)

}

此代码将覆盖文件的每一行。该行是否被修改取决于changeData修改的内容。


如果您想避免覆盖每一行,因为大多数行不需要更改,那么您必须寻找要覆盖数据的位置。


查看完整回答
反对 回复 2023-08-14
  • 1 回答
  • 0 关注
  • 101 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信