如何在Golang中删除大文件的前N个字节?

时间:2018-10-18 10:48:14

标签: go

我有一个大约10G的大文件,我想删除该文件的前10个字节。

如果我使用ioutil.ReadFile(),则整个文件将分配到内存中。无法做到!

另一个想法是我逐行读取此文件。在删除数据之后,我应该逐行写入其余数据。这样可以节省内存,但是是否存在更好的方法呢?像split还是readersplit文件一样?

1 个答案:

答案 0 :(得分:4)

在大多数文件系统上,您不能从文件的开头或中间“切出”一部分,而只能在文件末尾截断。

最简单的方法是打开源文件,跳过要剥离的部分(使用查找),打开目标文件,然后简单地从源复制到目标。

要进行搜索(跳过),请使用File.Seek()。要在文件之间复制,请使用io.Copy()

这是可以做到的:

fin, err := os.Open("source.txt")
if err != nil {
    panic(err)
}
defer fin.Close()

fout, err := os.Create("dest.txt")
if err != nil {
    panic(err)
}
defer fout.Close()

// Offset is the number of bytes you want to exclude
_, err = fin.Seek(10, io.SeekStart)
if err != nil {
    panic(err)
}

n, err := io.Copy(fout, fin)
fmt.Printf("Copied %d bytes, err: %v", n, err)

请注意,上面的代码将在新文件中获取所需的结果文件。如果您希望“新”文件变旧(即您不想使用其他文件),则在上述操作(如果成功之后)之后,请删除原始文件,然后将新文件重命名为旧文件。

这是您可以完成的最后步骤的方法:

if err := os.Remove("source.txt"); err != nil {
    panic(err)
}

if err := os.Rename("dest.txt", "source.txt"); err != nil {
    panic(err)
}