首页 > 其他分享 >go并发-读文件->管道->写文件->优雅退出

go并发-读文件->管道->写文件->优雅退出

时间:2022-09-20 16:23:10浏览次数:69  
标签:文件 string err fmt filename 并发 go path

并发读3个文件-开3个线程-插入管道-开1个线程写入新文件后优雅退出

package main

import (
	"bufio"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"sync"
)

var ch = make(chan string, 1000000) //  读文件插入的隧道
var write_main = make(chan struct{}) // 优雅退出main协程的空隧道
var wg_1 = sync.WaitGroup{} //优先等待读文件协程全部结束后 在执行下一步操作

//读目录下所有txt文件获取path+文件名 func FileName(path string) (string, []string) { filename := []string{} subDirs, err := ioutil.ReadDir(path) // fmt.Println(subDirs) if err != nil { return "nil", nil } for _, dir := range subDirs { if dir.IsDir() { FileName(filepath.Join(path, dir.Name())) } else { if strings.HasSuffix(dir.Name(), ".txt") { // fmt.Println(dir.Name()) filename = append(filename, dir.Name()) } } } return path, filename }

3个协程并发读文件 func ReadFile(path string, filename []string) { wg_1.Add(len(filename)) for _, v := range filename { go func(v string) { //读文件并发 path_filename := path + "/" + v fin, err := os.Open(path_filename) if err != nil { fmt.Printf("打开文件失败:%v\n", err) } defer fin.Close() reder := bufio.NewReader(fin) // Hostslice := []string{} for { line, err := reder.ReadString('\n') fmt.Println(line, "line") if err != nil { if err == io.EOF { break } else { fmt.Printf("读文件失败:%v\n", err) } } else { line = strings.TrimRight(line, "\n") ch <- line fmt.Println(line, "插入管道的每一行") } } wg_1.Done() }(v) } } func WriteFile(ch chan string) { f, err := os.OpenFile("dir/new.txt", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0777) if err != nil { fmt.Println("打开文件失败", err) } defer f.Close() for { v, ok := <-ch if !ok { break } else { writer := bufio.NewWriter(f) writer.WriteString(v + "\n") writer.Flush() fmt.Println(v, "write") } } <-write_main } func main() { path, filename := FileName("dir") ReadFile(path, filename) fmt.Println("当前存在的协程数量", runtime.NumGoroutine()) go WriteFile(ch) wg_1.Wait() //等读完文件 close(ch) //读完关闭文件 write_main <- struct{}{} //先插入一条进管道,然后write执行后取出管道 fmt.Println("当前存在的协程数量", runtime.NumGoroutine()) }

 

标签:文件,string,err,fmt,filename,并发,go,path
From: https://www.cnblogs.com/NeilyoX/p/16711451.html

相关文章

  • mangodb更新数组字符串为数组
    通过csv导入的数组类型数据会变为字符串类型,如:"[""A"",""B""]";"[1,2,3,4,5]",应为:["A","B"];[1,2,3,4,5]。批量更新代码:db.getCollection('pagedata').find({'pageDat......
  • Net5 控制台程序读取配置文件的几种方式
    十年河东,十年河西,莫欺少年穷学无止境,精益求精本篇提供几种读取配置文件的方式,从简到难,步步加深1、新建控制台程序1.1、新增一个名称为application.json的配置文件appl......
  • MongoDB集群的variety执行
    创建结果数据库   1.创建一个新的存储数据库用来保存分析结果     usekeyTest     db.createUser({       user:"root",   ......
  • go语言中使用接口,以及对接口的理解
    go语言中使用接口,以及对接口的理解接口的简单介绍在任一编程语言中,接口-方法或行为的集合,在功能和该功能的使用者之间构建了一层薄薄的抽象层。在使用接口时,并不需要了......
  • go ssl
    packagemainimport("github.com/gin-gonic/gin""log""net/http")//测试go语言证书访问//opensslgenrsa-outserver.key2048//opensslreq......
  • MySQL维护之日志文件
    MySQL数据库中常见的日志文件有错误日志(ErrorLog)、二进制日志(BinaryLog)、慢查询日志(SlowQueryLog)、全查询日志(GeneralQueryLog)、中继日志(RelayLog)和事务日志。......
  • Python读取文件夹按数字排序
    python中os.listdir()方法用于返回指定的文件夹包含的文件或文件夹的名字的列表importospath="../data/materials/test/"path_list=os.listdir(path)print(path......
  • googlepay-谷歌支付-一次性消耗inapp
    1.参考:https://zhuanlan.zhihu.com/p/5066367752.官方文档:https://developer.android.google.cn/google/play/billing/integrate3.Pub/subapi:https://cloud.google.com/......
  • pandas 处理数据并发送邮件
    知识点1:SQL读取并创建dataframe知识点2:python发送邮件知识点3:dataframe中某列series取唯一值知识点4:dataframe切片知识点5:dataframe中如何应用apply函数知识点6:函数的......
  • 进 线 协程IO模型 - 并发 同步 阻塞非阻塞
    #进程:进程就是一个程序在内存中的运行,进程是资源分配的最小单位#线程:线程是cup调度的最小单位#计算:消耗cpu,cpu进行运算#io:不消耗cpu#垃圾回收机制:垃圾回......