github.com/iikira/iikira-go-utils@v0.0.0-20230610031953-f2cb11cde33a/requester/rio/file.go (about) 1 package rio 2 3 import ( 4 cryptorand "crypto/rand" 5 "io" 6 "os" 7 "sync/atomic" 8 ) 9 10 type ( 11 fileReadedlen64 struct { 12 readed int64 13 f *os.File 14 } 15 16 rdReadedlen64 struct { 17 readed int64 18 size int64 19 rd io.Reader 20 } 21 ) 22 23 // NewFileReaderLen64 *os.File 实现 ReadedLen64 接口 24 func NewFileReaderLen64(f *os.File) ReaderLen64 { 25 if f == nil { 26 return nil 27 } 28 29 return &fileReadedlen64{ 30 f: f, 31 } 32 } 33 34 // NewFileReaderAtLen64 *os.File 实现 ReaderAtLen64 接口 35 func NewFileReaderAtLen64(f *os.File) ReaderAtLen64 { 36 if f == nil { 37 return nil 38 } 39 40 return &fileReadedlen64{ 41 f: f, 42 } 43 } 44 45 func NewCryptoRandReaderAtLen64(size int64) ReaderAtLen64 { 46 return &rdReadedlen64{ 47 rd: cryptorand.Reader, 48 size: size, 49 } 50 } 51 52 // Read 读文件, 并记录已读取数据量 53 func (fr *fileReadedlen64) Read(b []byte) (n int, err error) { 54 n, err = fr.f.Read(b) 55 atomic.AddInt64(&fr.readed, int64(n)) 56 return n, err 57 } 58 59 // ReadAt 读文件, 不记录已读取数据量 60 func (fr *fileReadedlen64) ReadAt(b []byte, off int64) (n int, err error) { 61 n, err = fr.f.ReadAt(b, off) 62 return n, err 63 } 64 65 // Len 返回文件的大小 66 func (fr *fileReadedlen64) Len() int64 { 67 info, err := fr.f.Stat() 68 if err != nil { 69 return 0 70 } 71 return info.Size() - fr.readed 72 } 73 74 func (rr *rdReadedlen64) Read(b []byte) (n int, err error) { 75 n, err = rr.ReadAt(b, 0) 76 atomic.AddInt64(&rr.readed, int64(n)) 77 return n, err 78 } 79 80 func (rr *rdReadedlen64) ReadAt(b []byte, off int64) (n int, err error) { 81 n, err = rr.rd.Read(b) 82 return n, err 83 } 84 85 func (rr *rdReadedlen64) Len() int64 { 86 return rr.size - rr.readed 87 }