使用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只在自己的块中写入数据。

下面放一个简单的实现,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
func main() {
    f,err := os.OpenFile("E:\\GO_worker\\src\\gota\\nihao.txt",os.O_RDWR,0666)<br>     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做计数。

我整理好了会在下篇帖子放一下符合实际应用的并发写入数据到文件 ,这篇帖子就写到这了。

 

posted on   thotf  阅读(1305)  评论(0编辑  收藏  举报

编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示