github.com/mondo192/jfrog-client-go@v1.0.0/utils/io/multifilereader.go (about) 1 package io 2 3 import ( 4 "github.com/mondo192/jfrog-client-go/utils/errorutils" 5 "io" 6 "os" 7 "sort" 8 ) 9 10 // Create new multi file ReaderAt 11 func NewMultiFileReaderAt(filePaths []string) (readerAt *multiFileReaderAt, err error) { 12 readerAt = &multiFileReaderAt{} 13 for _, v := range filePaths { 14 f, curErr := os.Open(v) 15 if curErr != nil { 16 return nil, curErr 17 } 18 defer func() { 19 e := f.Close() 20 if err == nil { 21 err = errorutils.CheckError(e) 22 } 23 }() 24 stat, curErr := f.Stat() 25 if curErr != nil { 26 return nil, curErr 27 } 28 29 readerAt.filesPaths = append(readerAt.filesPaths, v) 30 readerAt.sizeIndex = append(readerAt.sizeIndex, readerAt.size) 31 readerAt.size += stat.Size() 32 } 33 34 return readerAt, nil 35 } 36 37 type multiFileReaderAt struct { 38 filesPaths []string 39 size int64 40 sizeIndex []int64 41 } 42 43 // Get overall size of all the files. 44 func (multiFileReader *multiFileReaderAt) Size() int64 { 45 return multiFileReader.size 46 } 47 48 // ReadAt implementation for multi files 49 func (multiFileReader *multiFileReaderAt) ReadAt(p []byte, off int64) (n int, err error) { 50 // Search for the correct index to find the correct file offset 51 i := sort.Search(len(multiFileReader.sizeIndex), func(i int) bool { return multiFileReader.sizeIndex[i] > off }) - 1 52 53 readBytes := 0 54 for { 55 var f *os.File 56 f, err = os.Open(multiFileReader.filesPaths[i]) 57 if err != nil { 58 return 59 } 60 defer func() { 61 e := f.Close() 62 if err == nil { 63 err = errorutils.CheckError(e) 64 } 65 }() 66 relativeOff := off + int64(n) - multiFileReader.sizeIndex[i] 67 readBytes, err = f.ReadAt(p[n:], relativeOff) 68 n += readBytes 69 if len(p) == n { 70 // Finished reading enough bytes 71 return 72 } 73 if err != nil && err != io.EOF { 74 // Error 75 return 76 } 77 if i+1 == len(multiFileReader.filesPaths) { 78 // No more files to read from 79 return 80 } 81 // Read from the next file 82 i++ 83 } 84 // not suppose to get here 85 }