-
-
Save miku/6e9cdb5225a1814f1758d3b6793ae423 to your computer and use it in GitHub Desktop.
A reader type that can be checked for EOF without read.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"io" | |
"io/ioutil" | |
"log" | |
"os" | |
"sync/atomic" | |
) | |
// eofReader can be checked for EOF, without a Read. It keeps track of the | |
// number of bytes read and compares it to the file size, in case the | |
// underlying type is a file. | |
type eofReader struct { | |
r io.Reader | |
count uint64 | |
} | |
// AtEOF returns true, if the number of bytes read equals the file size. False | |
// otherwise. | |
func (r *eofReader) AtEOF() (bool, error) { | |
f, ok := r.r.(*os.File) | |
if !ok { | |
return false, nil | |
} | |
fi, err := f.Stat() | |
if err != nil { | |
return false, err | |
} | |
return r.Count() == uint64(fi.Size()), nil | |
} | |
// Read reads and counts. | |
func (r *eofReader) Read(buf []byte) (int, error) { | |
n, err := r.r.Read(buf) | |
atomic.AddUint64(&r.count, uint64(n)) | |
return n, err | |
} | |
// Count returns the count. | |
func (r *eofReader) Count() uint64 { | |
return atomic.LoadUint64(&r.count) | |
} | |
func main() { | |
f, err := os.Open("main.go") | |
if err != nil { | |
log.Fatal(err) | |
} | |
r := &eofReader{r: f} | |
log.Println(r.AtEOF()) | |
if _, err = ioutil.ReadAll(r); err != nil { | |
log.Fatal(err) | |
} | |
log.Println(r.AtEOF()) | |
} | |
// 2016/12/19 03:49:35 false <nil> | |
// 2016/12/19 03:49:35 true <nil> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment