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


      目录
      相关文章
      |
      3天前
      |
      编译器 Go 开发者
      go语言中导入相关包
      【11月更文挑战第1天】
      11 3
      |
      7天前
      |
      Unix Linux Go
      go进阶编程:Golang中的文件与文件夹操作指南
      本文详细介绍了Golang中文件与文件夹的基本操作,包括读取、写入、创建、删除和遍历等。通过示例代码展示了如何使用`os`和`io/ioutil`包进行文件操作,并强调了错误处理、权限控制和路径问题的重要性。适合初学者和有经验的开发者参考。
      |
      8天前
      |
      算法 大数据 Go
      Go文件操作:掌握Go的文件读写与操作技巧
      本文介绍了Go语言的文件操作功能,包括文件的打开、读写和关闭。Go语言通过`os`和`io`包提供了丰富的文件操作接口,使开发者能够轻松实现文件的读写和管理。文章详细讲解了核心概念、具体操作步骤和代码示例,并探讨了实际应用场景和未来发展趋势。
      |
      8天前
      |
      存储 前端开发 Go
      Go 文件的读取操作
      本文介绍了 Go 语言标准库中的 `os` 包和 `bufio` 包,重点讲解了 `os` 包中的 `Open` 和 `OpenFile` 函数及 `File` 结构体的 `Read` 方法,以及 `bufio` 包中的 `NewReader` 函数和 `Reader` 结构体的 `ReadString` 方法。通过示例代码展示了如何使用这些方法高效读取文件,减少磁盘操作。
      |
      10天前
      |
      并行计算 安全 Go
      Go语言的并发特性
      【10月更文挑战第26天】Go语言的并发特性
      6 1
      |
      15天前
      |
      Java 大数据 Go
      Go语言:高效并发的编程新星
      【10月更文挑战第21】Go语言:高效并发的编程新星
      40 7
      |
      20天前
      |
      安全 Go 调度
      探索Go语言的并发模式:协程与通道的协同作用
      Go语言以其并发能力闻名于世,而协程(goroutine)和通道(channel)是实现并发的两大利器。本文将深入了解Go语言中协程的轻量级特性,探讨如何利用通道进行协程间的安全通信,并通过实际案例演示如何将这两者结合起来,构建高效且可靠的并发系统。
      |
      20天前
      |
      安全 Go 开发者
      破译Go语言中的并发模式:从入门到精通
      在这篇技术性文章中,我们将跳过常规的摘要模式,直接带你进入Go语言的并发世界。你将不会看到枯燥的介绍,而是一段代码的旅程,从Go的并发基础构建块(goroutine和channel)开始,到高级模式的实践应用,我们共同探索如何高效地使用Go来处理并发任务。准备好,让Go带你飞。
      |
      21天前
      |
      安全 Go 调度
      探索Go语言的并发之美:goroutine与channel
      在这个快节奏的技术时代,Go语言以其简洁的语法和强大的并发能力脱颖而出。本文将带你深入Go语言的并发机制,探索goroutine的轻量级特性和channel的同步通信能力,让你在高并发场景下也能游刃有余。
      |
      18天前
      |
      安全 程序员 Go
      深入浅出Go语言的并发之道
      在本文中,我们将探索Go语言如何优雅地处理并发编程。通过对比传统多线程模型,我们将揭示Go语言独特的goroutine和channel机制是如何简化并发编程,并提高程序的效率和稳定性。本文不涉及复杂的技术术语,而是用通俗易懂的语言,结合生动的比喻,让读者能够轻松理解Go语言并发编程的核心概念。