github.com/hoffie/larasync@v0.0.0-20151025221940-0384d2bddcef/repository/chunker/chunker.go (about) 1 package chunker 2 3 import ( 4 "io" 5 "os" 6 ) 7 8 // Chunker returns the contents of the given file path in chunkSize-sized 9 // chunks. 10 type Chunker struct { 11 file *os.File 12 finished bool 13 chunkSize uint64 14 } 15 16 // New returns a new chunker instance for the given file path 17 // and the given chunk size. 18 func New(path string, chunkSize uint64) (*Chunker, error) { 19 file, err := os.Open(path) 20 if err != nil { 21 return nil, err 22 } 23 24 if chunkSize < 16 { 25 return nil, ErrBadChunkSize 26 } 27 28 c := &Chunker{ 29 file: file, 30 finished: false, 31 chunkSize: chunkSize, 32 } 33 return c, nil 34 } 35 36 // HasNext returns true if an upcoming Next() call is expected 37 // to return more data. 38 func (c *Chunker) HasNext() bool { 39 return !c.finished 40 } 41 42 // Next returns the next part of the file, with at most chunkSize bytes. 43 func (c *Chunker) Next() ([]byte, error) { 44 buf := make([]byte, c.chunkSize) 45 numBytes, err := c.file.Read(buf) 46 if uint64(numBytes) < c.chunkSize || err != nil { 47 c.finished = true 48 } 49 if err != nil || numBytes == 0 { 50 c.file.Close() 51 } 52 if err != nil && err != io.EOF { 53 return nil, err 54 } 55 return buf[:numBytes], nil 56 } 57 58 // Close cleans up the chunker after usage. 59 // 60 // Use the c := NewChunker(); defer c.Close() pattern 61 func (c *Chunker) Close() { 62 c.file.Close() 63 }