You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

clone.go 1.2 kB

1 year ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. package io2
  2. import (
  3. "io"
  4. "sync"
  5. )
  6. // 复制一个流。注:返回的多个流的读取不能在同一个线程,且如果不再需要读取返回的某个流,那么必须关闭这个流,否则会阻塞其他流的读取。
  7. func Clone(str io.Reader, count int) []io.ReadCloser {
  8. prs := make([]io.ReadCloser, count)
  9. pws := make([]*io.PipeWriter, count)
  10. for i := 0; i < count; i++ {
  11. prs[i], pws[i] = io.Pipe()
  12. }
  13. go func() {
  14. pwCount := count
  15. buf := make([]byte, 1024*16)
  16. var closeErr error
  17. for {
  18. if pwCount == 0 {
  19. return
  20. }
  21. rd, err := str.Read(buf)
  22. wg := sync.WaitGroup{}
  23. for i := 0; i < count; i++ {
  24. if pws[i] == nil {
  25. continue
  26. }
  27. wg.Add(1)
  28. go func(i int) {
  29. defer wg.Done()
  30. err := WriteAll(pws[i], buf[:rd])
  31. if err != nil {
  32. pws[i] = nil
  33. pwCount--
  34. }
  35. }(i)
  36. }
  37. wg.Wait()
  38. if err == nil {
  39. continue
  40. }
  41. closeErr = err
  42. break
  43. }
  44. for i := 0; i < count; i++ {
  45. if pws[i] == nil {
  46. continue
  47. }
  48. pws[i].CloseWithError(closeErr)
  49. }
  50. }()
  51. return prs
  52. }
  53. /*
  54. func BufferedClone(str io.Reader, count int, bufSize int) []io.ReadCloser {
  55. }
  56. */