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.4 kB

2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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. type readCloserHook struct {
  21. readCloser io.ReadCloser
  22. callback func(closer io.ReadCloser)
  23. isBefore bool // callback调用时机,true则在closer的Close之前调用
  24. }
  25. func (hook *readCloserHook) Read(buf []byte) (n int, err error) {
  26. return hook.readCloser.Read(buf)
  27. }
  28. func (hook *readCloserHook) Close() error {
  29. if hook.isBefore {
  30. hook.callback(hook.readCloser)
  31. }
  32. err := hook.readCloser.Close()
  33. if !hook.isBefore {
  34. hook.callback(hook.readCloser)
  35. }
  36. return err
  37. }
  38. func BeforeReadClosing(closer io.ReadCloser, callback func(closer io.ReadCloser)) io.ReadCloser {
  39. return &readCloserHook{
  40. readCloser: closer,
  41. callback: callback,
  42. isBefore: true,
  43. }
  44. }
  45. func AfterReadClosed(closer io.ReadCloser, callback func(closer io.ReadCloser)) io.ReadCloser {
  46. return &readCloserHook{
  47. readCloser: closer,
  48. callback: callback,
  49. isBefore: false,
  50. }
  51. }
  52. type readerWithCloser struct {
  53. reader io.Reader
  54. closer func(reader io.Reader) error
  55. }
  56. func (hook *readerWithCloser) Read(buf []byte) (n int, err error) {
  57. return hook.reader.Read(buf)
  58. }
  59. func (c *readerWithCloser) Close() error {
  60. return c.closer(c.reader)
  61. }
  62. func WithCloser(reader io.Reader, closer func(reader io.Reader) error) io.ReadCloser {
  63. return &readerWithCloser{
  64. reader: reader,
  65. closer: closer,
  66. }
  67. }
  68. type LazyReadCloser struct {
  69. open func() (io.ReadCloser, error)
  70. stream io.ReadCloser
  71. }
  72. func (r *LazyReadCloser) Read(buf []byte) (n int, err error) {
  73. if r.stream == nil {
  74. var err error
  75. r.stream, err = r.open()
  76. if err != nil {
  77. return 0, err
  78. }
  79. }
  80. return r.stream.Read(buf)
  81. }
  82. func (r *LazyReadCloser) Close() error {
  83. if r.stream == nil {
  84. return nil
  85. }
  86. return r.stream.Close()
  87. }
  88. func Lazy(open func() (io.ReadCloser, error)) *LazyReadCloser {
  89. return &LazyReadCloser{
  90. open: open,
  91. }
  92. }
  93. func ToReaders(strs []io.ReadCloser) ([]io.Reader, func()) {
  94. var readers []io.Reader
  95. for _, s := range strs {
  96. readers = append(readers, s)
  97. }
  98. return readers, func() {
  99. for _, s := range strs {
  100. s.Close()
  101. }
  102. }
  103. }