Go语言 协程配合管道的综合案例-2

   日期:2020-05-24     浏览:106    评论:0    
核心提示:package mainimport ( bufio fmt math/rand os sort strconv time)func main() { //初始化一个种子用来生成随机数据 rand.Seed(time.Now().UnixNano()) //文件写入状态 writerChanOk := make(chan bool, 10) //1.开一个协程writeDataTofile,随机生成1000个数据,存放到文件中 pathN
package main

import (
	"bufio"
	"math/rand"
	"os"
	"sort"
	"strconv"
	"time"
)

func main() {

	//初始化一个种子用来生成随机数据
	rand.Seed(time.Now().UnixNano())

	//文件写入状态
	writerChanOk := make(chan<- bool, 10)

	//1.开一个协程writeDataTofile,随机生成1000个数据,存放到文件中
	pathNameBefore := "d:/writeDataFile_" //在D盘根目录生成一个文件名以writeDataFile_开头的文件
	pathNameRear := ".txt"                //文件后缀

	for i := 0; i < 10; i++ {
		//开启十个协程
		go func(pathNameLeft, pathNameRight string, i int, writerChanOk chan<- bool) {
			file, err := os.OpenFile(pathNameLeft+strconv.Itoa(i)+pathNameRight, os.O_CREATE|os.O_TRUNC, 0777)
			if err != nil {
				panic(err)
			}
			defer file.Close()
			writer := bufio.NewWriter(file)
			for i := 0; i < 1000; i++ {
				//往文件写入指定范围随机字符数据
				writer.WriteString(string(rand.Int63n('z'-'A') + 'A'))
			}
			writer.Flush()
			//写入文件 完成一次 状态
			writerChanOk <- true
		}(pathNameBefore, pathNameRear, i, writerChanOk)
	}

	for {
		//判断协程是否写入完成
		if len(writerChanOk) == 10 {
			//关闭文件写入状态管道
			close(writerChanOk)
			break
		}
	}

	//数据管道
	dataChan := make(chan string, 10)
	//协程完成状态
	appear := make(chan<- bool, 10)

	//2.当writeDataFile完成写1000个数据到文件后,让sort协程从文件中读取1000个数据并排序,
	//3.考察点:协程和管道+文件的综合使用
	for i := 0; i < 10; i++ {
		go func(pathNameLeft, pathNameRight string, i int, dataChan chan string, appear chan<- bool) {
			file, err := os.OpenFile(pathNameLeft+strconv.Itoa(i)+pathNameRight, os.O_RDONLY, 0777)
			if err != nil {
				panic(err)
			}
			defer file.Close()
			//创建一个Int切片用于排序
			intSlice := &[]int{}
			reader := bufio.NewReader(file)
			for j := 0; j < 1000; j++ {
				data, _ := reader.ReadByte()
				//循环读取一千个字节并存入Int切片
				*intSlice = append(*intSlice, int(data))
			}
			//排序
			sort.Ints(*intSlice)
			str := ""
			for j := 0; j < len(*intSlice); j++ {
				//转为字符串
				str += string(byte((*intSlice)[j]))
			}
			//字符串数据存入管道
			dataChan <- str
			appear <- true
		}(pathNameBefore, pathNameRear, i, dataChan, appear)
	}

	go func() {
		for {
			//判断协程是否完成任务
			if len(appear) == 10 {
				//关闭数据管道
				close(dataChan)
				close(appear)
				break
			}
		}
	}()

	//重新写入文件状态
	writeStatus := make(chan<- bool, 10)

	//4.功能拓展开10个协程writeDataTofile,每隔协程随机生成1000个数据,存放到10个文件
	//5.当10个文件都生成了,让10个sort协程从10文件中读取1000个数据,并完成排序重新写入到10个结果文件。
	i := 0
	for v := range dataChan {
		go func(pathNameLeft, pathNameRight string, i int, writeStatus chan<- bool) {
			file, err := os.OpenFile(pathNameLeft+strconv.Itoa(i)+pathNameRight, os.O_CREATE|os.O_APPEND, 0777)
			if err != nil {
				panic(err)
			}
			defer file.Close()
			writer := bufio.NewWriter(file)
			//原要求是让覆盖重新写入,这里改为追加
			writer.WriteString("\n" + v)
			writer.Flush()
			writeStatus <- true
		}(pathNameBefore, pathNameRear, i, writeStatus)
		i++
	}
	for {
		if len(writeStatus) == 10 {
			break
		}
	}
}

运行效果


 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服