package export import ( "bytes" "encoding/csv" "fmt" "log" "os" "os/exec" "strconv" "strings" "testing" "time" ) // https://bbs.huaweicloud.com/blogs/286321 var tFmt = "2006-01-02 15:04:05" // 第二步模拟获取数据,然后批量导出多个文件,然后合并一个文件 func Test_export(t *testing.T) { content := readFile() fmt.Printf("%s - read file end......%d\n", time.Now().Format(tFmt), len(content)) exportFile(content) time.Sleep(time.Millisecond * 200) } // 第一步测试数据 func Test_write(t *testing.T) { f, err := os.Create("test.csv") if err != nil { panic(err) } defer f.Close() f.WriteString("\xEF\xBB\xBF") // 写入UTF-8 BOM w := csv.NewWriter(f) str := []string{"xxx", "ewewe", "werwe", ""} for i := 1; i <= 100*10000; i++ { str[3] = strconv.Itoa(i) w.Write(str) } w.Flush() } func readFile() [][]string { //准备读取文件 fileName := "test.csv" fmt.Printf("%s - read file......\n", time.Now().Format(tFmt)) fs1, _ := os.Open(fileName) r1 := csv.NewReader(fs1) content, err := r1.ReadAll() if err != nil { log.Fatalf("can not readall, err is %+v", err) } return content } func exportFile(content [][]string) { fmt.Printf("%s - start export multiple file......\n", time.Now().Format(tFmt)) length := len(content) // 2. 并发循环导出,一次200,000 (20万数据) 到 1个文件,最终输出n个10万数据的文件 count := 1 pos := 0 fileNameArr := make([]string, 0) for pos < length { maxPos := pos + 20*10000 if maxPos > length { maxPos = length } temp := content[pos:maxPos] go wiriteTempFile(pos, "temp"+strconv.Itoa(count)+".csv", temp) fileNameArr = append(fileNameArr, "temp"+strconv.Itoa(count)+".csv") count++ pos += 20 * 10000 } // 3. 合并n个文件到1个文件 var outBytes bytes.Buffer fileNameStr := strings.Join(fileNameArr, " ") cmdStr := fmt.Sprintf("cat %s > testall.csv", fileNameStr) cmd := exec.Command("sh", "-c", cmdStr) cmd.Stdout = &outBytes err := cmd.Run() if err != nil { log.Println(err) return } resStr := outBytes.String() log.Println(resStr, cmdStr) fmt.Printf("%s - export file success......\n", time.Now().Format(tFmt)) } func wiriteTempFile(pos int, file string, data [][]string) { fmt.Printf("len === %d , pos=%d \n", len(data), pos) f, err := os.Create(file) if err != nil { panic(err) } defer f.Close() f.WriteString("\xEF\xBB\xBF") // 写入UTF-8 BOM w := csv.NewWriter(f) w.WriteAll(data) w.Flush() } // 创建文件夹 func MakeDir(dir string) error { if !FileIsExisted(dir) { if err := os.MkdirAll(dir, 0777); err != nil { //os.ModePerm fmt.Println("MakeDir failed:", err) return err } } return nil } // 检测文件是否存在 func FileIsExisted(filename string) bool { existed := true if _, err := os.Stat(filename); os.IsNotExist(err) { existed = false } return existed }