1. 省份划分

根据身份证号的前2位把数据划分到不同的省份文件里面

  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "io"
  6. "os"
  7. "strings"
  8. "sync"
  9. )
  10. // 按照34个省划分数据
  11. // 1.创建34个省份,创建34个数据管道
  12. // 2.读优质数据,写入对应省份管道
  13. // 3.把省份管道写道对应文件,开34个协程
  14. // 抽象出一个省份对象
  15. type Province struct {
  16. // Id 身份证前2位
  17. Id string
  18. // 省份名
  19. Name string
  20. // 该省对应的文件,例如 北京.txt
  21. File *os.File
  22. // 本省文件的数据管道
  23. chanData chan string
  24. }
  25. // 声明等待组
  26. var wg sync.WaitGroup
  27. func main() {
  28. // 声明个map,存放所有省市的
  29. pMap := make(map[string]*Province)
  30. ps := []string{"北京市11", "天津市12", "河北省13",
  31. "山西省14", "内蒙古自治区15", "辽宁省21", "吉林省22",
  32. "黑龙江省23", "上海市31", "江苏省32", "浙江省33", "安徽省34",
  33. "福建省35", "江西省36", "山东省37", "河南省41", "湖北省42",
  34. "湖南省43", "广东省44", "广西壮族自治区45", "海南省46",
  35. "重庆市50", "四川省51", "贵州省52", "云南省53", "西藏自治区54",
  36. "陕西省61", "甘肃省62", "青海省63", "宁夏回族自治区64", "新疆维吾尔自治区65",
  37. "香港特别行政区81", "澳门特别行政区82", "台湾省83"}
  38. // 遍历所有省市,创建实例,省份管道创建
  39. for _, p := range ps {
  40. name := p[:len(p)-2]
  41. id := p[len(p)-2:]
  42. // 创建对象
  43. province := Province{Id: id, Name: name}
  44. // 添加进map
  45. pMap[id] = &province
  46. // 为当前省份开一个文件
  47. file, _ := os.OpenFile("./"+province.Name+".txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
  48. province.File = file
  49. defer file.Close()
  50. // 创建当前省份管道
  51. province.chanData = make(chan string, 1024)
  52. fmt.Println(name, "管道已创建")
  53. }
  54. // 遍历34个省份,开34个对应文件写数据
  55. for _, province := range pMap {
  56. wg.Add(1)
  57. // 写入数据,这里是map中的地址
  58. go writeFile(province)
  59. }
  60. // 读优质文件,写入对应的省份管道
  61. file, _ := os.Open("./kaifang_good.txt")
  62. defer file.Close()
  63. // 缓冲读取
  64. reader := bufio.NewReader(file)
  65. // 逐行读
  66. for {
  67. lineBytes, _, err := reader.ReadLine()
  68. if err == io.EOF {
  69. for _, province := range pMap {
  70. close(province.chanData)
  71. fmt.Println(province.Name, "管道已经关闭")
  72. }
  73. break
  74. }
  75. // 转str,转utf
  76. lineStr := string(lineBytes)
  77. // 逗号切分
  78. fieldsSlice := strings.Split(lineStr, ",")
  79. id := fieldsSlice[1][0:2]
  80. // 对号入座,写入对应管道
  81. if provice, ok := pMap[id]; ok {
  82. provice.chanData <- (lineStr + "\n")
  83. } else {
  84. fmt.Println("未知的省", id)
  85. }
  86. }
  87. wg.Wait()
  88. }
  89. // 向文件写数据
  90. func writeFile(province *Province) {
  91. for lineStr := range province.chanData {
  92. province.File.WriteString(lineStr)
  93. fmt.Print(province.Name, "写入", lineStr)
  94. }
  95. wg.Done()
  96. }