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

我正在尝试逐行读取一个非常大的文件,然后替换行中的某些内容并写回同一个文件。我找不到办法做到这一点。目前我已经创建了一个临时文件并将替换的行保存在临时文件中,最后将临时文件内容复制到原始文件中。但我必须进行两次读取和两次写入。我想避免这种情况。有任何想法吗。


以下是我尝试过的:


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


互换的青春
浏览 74回答 1
1回答

临摹微笑

解决方案是打开文件两次,第一次用于读取,第二次用于覆盖内容。请参阅下面的代码。请注意,我使用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修改的内容。如果您想避免覆盖每一行,因为大多数行不需要更改,那么您必须寻找要覆盖数据的位置。
打开App,查看更多内容
随时随地看视频慕课网APP