go并发-读文件->管道->写文件->优雅退出
并发读3个文件-开3个线程-插入管道-开1个线程写入新文件后优雅退出
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | 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{} //优先等待读文件协程全部结束后 在执行下一步操作 <br> //读目录下所有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 }<br><br>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()) } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构