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 2.9 kB

2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. package io
  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 readerWithCloser struct {
  75. reader io.Reader
  76. closer func(reader io.Reader) error
  77. }
  78. func (hook *readerWithCloser) Read(buf []byte) (n int, err error) {
  79. return hook.reader.Read(buf)
  80. }
  81. func (c *readerWithCloser) Close() error {
  82. return c.closer(c.reader)
  83. }
  84. func WithCloser(reader io.Reader, closer func(reader io.Reader) error) io.ReadCloser {
  85. return &readerWithCloser{
  86. reader: reader,
  87. closer: closer,
  88. }
  89. }
  90. type LazyReadCloser struct {
  91. open func() (io.ReadCloser, error)
  92. stream io.ReadCloser
  93. }
  94. func (r *LazyReadCloser) Read(buf []byte) (n int, err error) {
  95. if r.stream == nil {
  96. var err error
  97. r.stream, err = r.open()
  98. if err != nil {
  99. return 0, err
  100. }
  101. }
  102. return r.stream.Read(buf)
  103. }
  104. func (r *LazyReadCloser) Close() error {
  105. if r.stream == nil {
  106. return nil
  107. }
  108. return r.stream.Close()
  109. }
  110. func Lazy(open func() (io.ReadCloser, error)) *LazyReadCloser {
  111. return &LazyReadCloser{
  112. open: open,
  113. }
  114. }
  115. func ToReaders(strs []io.ReadCloser) ([]io.Reader, func()) {
  116. var readers []io.Reader
  117. for _, s := range strs {
  118. readers = append(readers, s)
  119. }
  120. return readers, func() {
  121. for _, s := range strs {
  122. s.Close()
  123. }
  124. }
  125. }