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

在 go 中缓冲读写相同的文件

在 go 中缓冲读写相同的文件

Go
素胚勾勒不出你 2022-04-26 15:20:56
我正在尝试逐行读取一个非常大的文件并替换行中的内容并写回同一个文件。我无法找到一种方法来做到这一点。目前我已经创建了一个临时文件并将替换的行保存在临时文件中,最后将临时文件内容复制到原始文件中。但我必须进行两次读取和两次写入。我想避免这种情况。有任何想法吗。以下是我尝试过的: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贡献1811条经验 获得超5个赞

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


请参阅下面的代码。


请注意,我使用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。


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


查看完整回答
反对 回复 2022-04-26
  • 1 回答
  • 0 关注
  • 154 浏览
慕课专栏
更多

添加回答

举报

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