storage/piece_file.go | 35 +++++++++++++++++++++++++---------- diff --git a/storage/piece_file.go b/storage/piece_file.go index c9fc3c2187f6327bceabf5980590c1522e19ed3b..95b2af0b9ee3e279e2775e0d6d3dc9c7177fe64d 100644 --- a/storage/piece_file.go +++ b/storage/piece_file.go @@ -59,22 +59,37 @@ func (me pieceFileTorrentStoragePiece) MarkComplete() error { return me.fs.Rename(me.incompletePath(), me.completedPath()) } +func (me pieceFileTorrentStoragePiece) openFile() (f missinggo.File, err error) { + f, err = me.fs.OpenFile(me.completedPath(), os.O_RDONLY) + if err == nil { + var fi os.FileInfo + fi, err = f.Stat() + if err == nil && fi.Size() == me.p.Length() { + return + } + f.Close() + } else if !os.IsNotExist(err) { + return + } + f, err = me.fs.OpenFile(me.incompletePath(), os.O_RDONLY) + if os.IsNotExist(err) { + err = io.ErrUnexpectedEOF + } + return +} + func (me pieceFileTorrentStoragePiece) ReadAt(b []byte, off int64) (n int, err error) { - f, err := me.fs.OpenFile(me.completedPath(), os.O_RDONLY) + f, err := me.openFile() if err != nil { - f, err = me.fs.OpenFile(me.incompletePath(), os.O_RDONLY) - if os.IsNotExist(err) { - err = io.ErrUnexpectedEOF - return - } - if err != nil { - return - } + return } defer f.Close() + missinggo.LimitLen(&b, me.p.Length()-off) n, err = f.ReadAt(b, off) off += int64(n) - if err == io.EOF && off < me.p.Length() { + if off >= me.p.Length() { + err = io.EOF + } else if err == io.EOF { err = io.ErrUnexpectedEOF } return