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.

io.go 3.8 kB

1 year ago
2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. package io2
  2. import "io"
  3. type PromiseWriteCloser[T any] interface {
  4. io.Writer
  5. Abort(err error) // 中断发送文件
  6. Finish() (T, error) // 发送文件完成,等待返回结果
  7. }
  8. func WriteAll(writer io.Writer, data []byte) error {
  9. pos := 0
  10. dataLen := len(data)
  11. for pos < dataLen {
  12. writeLen, err := writer.Write(data[pos:])
  13. if err != nil {
  14. return err
  15. }
  16. pos += writeLen
  17. }
  18. return nil
  19. }
  20. const (
  21. onceDisabled = 0
  22. onceEnabled = 1
  23. onceDone = 2
  24. )
  25. type readCloserHook struct {
  26. readCloser io.ReadCloser
  27. callback func(closer io.ReadCloser)
  28. once int
  29. isBefore bool // callback调用时机,true则在closer的Close之前调用
  30. }
  31. func (hook *readCloserHook) Read(buf []byte) (n int, err error) {
  32. return hook.readCloser.Read(buf)
  33. }
  34. func (hook *readCloserHook) Close() error {
  35. if hook.once == onceDone {
  36. return hook.readCloser.Close()
  37. }
  38. if hook.isBefore {
  39. hook.callback(hook.readCloser)
  40. }
  41. err := hook.readCloser.Close()
  42. if !hook.isBefore {
  43. hook.callback(hook.readCloser)
  44. }
  45. if hook.once == onceEnabled {
  46. hook.once = onceDone
  47. }
  48. return err
  49. }
  50. func BeforeReadClosing(closer io.ReadCloser, callback func(closer io.ReadCloser)) io.ReadCloser {
  51. return &readCloserHook{
  52. readCloser: closer,
  53. callback: callback,
  54. once: onceDisabled,
  55. isBefore: true,
  56. }
  57. }
  58. func AfterReadClosed(closer io.ReadCloser, callback func(closer io.ReadCloser)) io.ReadCloser {
  59. return &readCloserHook{
  60. readCloser: closer,
  61. callback: callback,
  62. once: onceDisabled,
  63. isBefore: false,
  64. }
  65. }
  66. func AfterReadClosedOnce(closer io.ReadCloser, callback func(closer io.ReadCloser)) io.ReadCloser {
  67. return &readCloserHook{
  68. readCloser: closer,
  69. callback: callback,
  70. once: onceEnabled,
  71. isBefore: false,
  72. }
  73. }
  74. type afterEOF struct {
  75. inner io.ReadCloser
  76. callback func(str io.ReadCloser, err error)
  77. }
  78. func (hook *afterEOF) Read(buf []byte) (n int, err error) {
  79. n, err = hook.inner.Read(buf)
  80. if hook.callback != nil {
  81. if err == io.EOF {
  82. hook.callback(hook.inner, nil)
  83. hook.callback = nil
  84. } else if err != nil {
  85. hook.callback(hook.inner, err)
  86. hook.callback = nil
  87. }
  88. }
  89. return n, err
  90. }
  91. func (hook *afterEOF) Close() error {
  92. err := hook.inner.Close()
  93. if hook.callback != nil {
  94. hook.callback(hook.inner, io.ErrClosedPipe)
  95. hook.callback = nil
  96. }
  97. return err
  98. }
  99. func AfterEOF(str io.ReadCloser, callback func(str io.ReadCloser, err error)) io.ReadCloser {
  100. return &afterEOF{
  101. inner: str,
  102. callback: callback,
  103. }
  104. }
  105. type readerWithCloser struct {
  106. reader io.Reader
  107. closer func(reader io.Reader) error
  108. }
  109. func (hook *readerWithCloser) Read(buf []byte) (n int, err error) {
  110. return hook.reader.Read(buf)
  111. }
  112. func (c *readerWithCloser) Close() error {
  113. return c.closer(c.reader)
  114. }
  115. func WithCloser(reader io.Reader, closer func(reader io.Reader) error) io.ReadCloser {
  116. return &readerWithCloser{
  117. reader: reader,
  118. closer: closer,
  119. }
  120. }
  121. type LazyReadCloser struct {
  122. open func() (io.ReadCloser, error)
  123. stream io.ReadCloser
  124. }
  125. func (r *LazyReadCloser) Read(buf []byte) (n int, err error) {
  126. if r.stream == nil {
  127. var err error
  128. r.stream, err = r.open()
  129. if err != nil {
  130. return 0, err
  131. }
  132. }
  133. return r.stream.Read(buf)
  134. }
  135. func (r *LazyReadCloser) Close() error {
  136. if r.stream == nil {
  137. return nil
  138. }
  139. return r.stream.Close()
  140. }
  141. func Lazy(open func() (io.ReadCloser, error)) *LazyReadCloser {
  142. return &LazyReadCloser{
  143. open: open,
  144. }
  145. }
  146. func ToReaders(strs []io.ReadCloser) ([]io.Reader, func()) {
  147. var readers []io.Reader
  148. for _, s := range strs {
  149. readers = append(readers, s)
  150. }
  151. return readers, func() {
  152. for _, s := range strs {
  153. s.Close()
  154. }
  155. }
  156. }
  157. func DropWithBuf(str io.Reader, buf []byte) error {
  158. for {
  159. _, err := str.Read(buf)
  160. if err == io.EOF {
  161. return nil
  162. }
  163. if err != nil {
  164. return err
  165. }
  166. }
  167. }