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
}
}
}
运行效果