使用os.WriteAt 分块写入数据
最近在写一个并发写入数据到文件的功能。使用到os.WriteAt方法
先看下官方给的文档
func (*File) WriteAt ¶
func (f *File) WriteAt(b []byte, off int64) (n int, err error)
WriteAt在指定的位置(相对于文件开始位置)写入len(b)字节数据。它返回写入的字节数和可能遇到的任何错误。如果返回值n!=len(b),本方法会返回一个非nil的错误。
参数
b 是我们要写入数据的字节切片
off 是相对位置
注意:
WriteAt 方法会在你给的off位置写入数据,如果off处有其他数据会直接覆盖掉比如:
源文件内容:
abcde
你的写入数据:
f.WriteAt([]byte("HHH"),1)
源文件改为:
aHHHe
注意2
在windows中换行是\r\n 在linux中换行是\n
例如在windows中修改源文件:
abc
abc
你的写入数据:
f.WriteAt([]byte("HHH"),3)
源文件改为:
abcHHHbc
就是因为你在位置 [3,5]写入HHH,原来[3,5]的数据是\r\na 这三个字节被覆盖掉了
所以在并发使用writeAt写数据要注意给文件位置分好"块"。

每一个goroutine只在自己的块中写入数据。
下面放一个简单的实现,
func main() {
f,err := os.OpenFile("E:\\GO_worker\\src\\gota\\nihao.txt",os.O_RDWR,0666)
defer f.Close()
if err!= nil {
fmt.Println(err)
os.Exit(-1)
}
for i:=0;i<3;i++{
var offset int64
offset = int64(i*5)
go func(a int64) {
n,err := f.WriteAt([]byte("abc\r\n"),a)
if err != nil {
fmt.Println(n,err)
}
}(offset)
}
time.Sleep(2*time.Second)
}
效果

我的这段代码是写死了offset不利于实际应用只是方便理解。
并发写入数据思路:需要用到原子操作给offset做计数。
我整理好了会在下篇帖子放一下符合实际应用的并发写入数据到文件 ,这篇帖子就写到这了。
浙公网安备 33010602011771号