GO 利用bufio包(流式操作) - 并发写文件/读文件示例

简介: GO 利用bufio包(流式操作) - 并发写文件/读文件示例

 并发写文件:

注意点:

    • runtime.GOMAXPROCS(runtime.NumCPU()) 限制并发写操作的协程数:

    协程数不宜过多,避免协程间的频繁切换影响性能(根据cpu核数而定)

    • WriteString()操作要加锁,否则最终写入数据有问题(乱码等...)
    • 最后记得Flush()一下:

    bufio 通过 flush 操作将缓冲写入真实的文件的,所以一定要在关闭文件之前先flush,否则会造成数据丢失的情况

    packagemainimport (
    "bufio""fmt""os""runtime""runtime/debug""sync")
    // bufio库的流式处理  如果文件较小,使用ioutil也不失为一种方法funcWriteDataToTxt() {
    txtFile, err :=os.OpenFile("55555.txt", os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777) // O_TRUNC 清空重写iferr!=nil {
    fmt.Println("WriteDataToTxt os.OpenFile() err:", err)
    return    }
    defertxtFile.Close()
    // txtFile.WriteString() // os操作文件-效率低bufWriter :=bufio.NewWriter(txtFile)
    varwgsync.WaitGrouplimitChan :=make(chanstruct{}, runtime.GOMAXPROCS(runtime.NumCPU())) // 最大并发协程数varmutexsync.Mutexfori :=0; i<10000; i++ { // 写1w行测试limitChan<-struct{}{}
    wg.Add(1)
    gofunc(jint) {
    deferfunc() {
    ife :=recover(); e!=nil {
    fmt.Printf("WriteDataToTxt panic: %v,stack: %s\n", e, debug.Stack())
    // return                }
    wg.Done()
    <-limitChan            }()
    // 模拟业务逻辑:先整合所有数据,然后再统一写WriteString()strId :=fmt.Sprintf("%v", j)
    strName :=fmt.Sprintf(" user_%v", j)
    strScore :=fmt.Sprintf(" %d", j*10)
    mutex.Lock() // 要加锁/解锁,否则 bufWriter.WriteString 写入数据有问题_, err :=bufWriter.WriteString(strId+strName+strScore+"\n")
    iferr!=nil {
    fmt.Printf("WriteDataToTxt WriteString err: %v\n", err)
    return            }
    mutex.Unlock()
    // bufWriter.Flush() // 刷入磁盘(错误示例:WriteDataToTxt err: short write,short write;因为循环太快,有时写入的数据量太小了)        }(i)
        }
    wg.Wait()
    bufWriter.Flush() // 刷入磁盘(正确示例,bufio 通过 flush 操作将缓冲写入真实的文件的,所以一定要在关闭文件之前先flush,否则会造成数据丢失的情况)}

    image.gif

    报错:

    image.gif编辑

    读文件:

    注意点:

      • 读取文件中一行内容时,ReadSliceReadLine性能优于ReadBytesReadString,但由于ReadLine对换行的处理更加全面(兼容\n\r\n换行),因此,实际开发过程中,建议使用ReadLine函数。
      • 关于os.File、bufio、ioutil 写文件的性能比较,参考:
        https://segmentfault.com/a/1190000023691973
      packagemainimport (
      "bufio""fmt""io""os")
      // 读文件funcReadDataFromTxt() {
      txtFile, err :=os.OpenFile("55555.txt", os.O_RDONLY, 0777) // O_TRUNC 清空重写iferr!=nil {
      fmt.Println("WriteDataToTxt os.OpenFile() err:", err)
      return    }
      defertxtFile.Close()
      bufReader :=bufio.NewReader(txtFile)
      for {
      data, _, err :=bufReader.ReadLine() // 读一行日志iferr==io.EOF {                   // 如果列表读完了,退出fmt.Println("数据读完了~")
      break        }
      fmt.Println("data: ", string(data))
          }
      return}

      image.gif


      目录
      相关文章
      |
      11月前
      |
      Linux Go iOS开发
      Go语言100个实战案例-进阶与部署篇:使用Go打包生成可执行文件
      本文详解Go语言打包与跨平台编译技巧,涵盖`go build`命令、多平台构建、二进制优化及资源嵌入(embed),助你将项目编译为无依赖的独立可执行文件,轻松实现高效分发与部署。
      1599 162
      |
      10月前
      |
      存储 监控 算法
      防止员工泄密软件中文件访问日志管理的 Go 语言 B + 树算法
      B+树凭借高效范围查询与稳定插入删除性能,为防止员工泄密软件提供高响应、可追溯的日志管理方案,显著提升海量文件操作日志的存储与检索效率。
      292 2
      |
      JSON 中间件 Go
      Go语言实战指南 —— Go中的反射机制:reflect 包使用
      Go语言中的反射机制通过`reflect`包实现,允许程序在运行时动态检查变量类型、获取或设置值、调用方法等。它适用于初中级开发者深入理解Go的动态能力,帮助构建通用工具、中间件和ORM系统等。
      763 63
      |
      10月前
      |
      Java 编译器 Go
      【Golang】(1)Go的运行流程步骤与包的概念
      初次上手Go语言!先来了解它的运行流程吧! 在Go中对包的概念又有怎样不同的见解呢?
      455 4
      |
      存储 Go 开发者
      Go 语言中如何处理并发错误
      在 Go 语言中,并发编程中的错误处理尤为复杂。本文介绍了几种常见的并发错误处理方法,包括 panic 的作用范围、使用 channel 收集错误与结果,以及使用 errgroup 包统一管理错误和取消任务,帮助开发者编写更健壮的并发程序。
      253 4
      Go 语言中如何处理并发错误
      |
      数据采集 JSON 自然语言处理
      Go语言实战案例-统计文件中每个字母出现频率
      《Go语言100个实战案例》中的“文件与IO操作篇 - 案例19”教你如何统计文本文件中每个英文字母的出现频率。通过实战练习,掌握文件读取、字符处理、map统计等基础技能,适合Go语言初学者提升编程能力。
      |
      数据采集 Go
      Go语言实战案例-批量重命名文件
      《Go语言100个实战案例》中的“文件与IO操作篇 - 案例17:批量重命名文件”,适合初学者学习使用 Go 操作文件系统,实现文件批量重命名功能,包括添加前缀、后缀或编号等。
      |
      JSON 缓存 Go
      Go语言实战案例-向文件写入内容
      本案例讲解如何使用 Go 语言向文件写入内容,涵盖覆盖写入与追加写入两种模式,适用于日志记录、报告生成等场景。涉及 `os.WriteFile`、`os.OpenFile` 等核心函数,并演示如何处理文件权限与编码问题。
      |
      数据采集 Go API
      Go语言实战案例:多协程并发下载网页内容
      本文是《Go语言100个实战案例 · 网络与并发篇》第6篇,讲解如何使用 Goroutine 和 Channel 实现多协程并发抓取网页内容,提升网络请求效率。通过实战掌握高并发编程技巧,构建爬虫、内容聚合器等工具,涵盖 WaitGroup、超时控制、错误处理等核心知识点。
      |
      缓存 监控 安全
      告别缓存击穿!Go 语言中的防并发神器:singleflight 包深度解析
      在高并发场景中,多个请求同时访问同一资源易导致缓存击穿、数据库压力过大。Go 语言提供的 `singleflight` 包可将相同 key 的请求合并,仅执行一次实际操作,其余请求共享结果,有效降低系统负载。本文详解其原理、实现及典型应用场景,并附示例代码,助你掌握高并发优化技巧。
      795 0

      热门文章

      最新文章