func (br *BlockReader) Close() error {
	br.closed = true
	if br.conn != nil {
		br.conn.Close()
	}
	return nil
}
Close implements io.Closer.
package rpc
import (
	"errors"
	"fmt"
	"hash/crc32"
	"io"
	"io/ioutil"
	"net"
	hdfs "github.com/colinmarc/hdfs/protocol/hadoop_hdfs"
	"github.com/golang/protobuf/proto"
)
type BlockReader struct {
	clientName string
	block      *hdfs.LocatedBlockProto
	datanodes  *datanodeFailover
	stream     *blockReadStream
	conn       net.Conn
	offset     int64
	closed     bool
}
func NewBlockReader(block *hdfs.LocatedBlockProto, offset int64, clientName string) *BlockReader {
	locs := block.GetLocs()
	datanodes := make([]string, len(locs))
	for i, loc := range locs {
		datanodes[i] = getDatanodeAddress(loc)
	}
	return &BlockReader{
		clientName: clientName,
		block:      block,
		datanodes:  newDatanodeFailover(datanodes),
		offset:     offset,
	}
}
func (br *BlockReader) Read(b []byte) (int, error) {
	if br.closed {
		return 0, io.ErrClosedPipe
	} else if uint64(br.offset) >= br.block.GetB().GetNumBytes() {
		br.Close()
		return 0, io.EOF
	}
	for br.stream != nil || br.datanodes.numRemaining() > 0 {
		if br.stream == nil {
			err := br.connectNext()
			if err != nil {
				br.datanodes.recordFailure(err)
				continue
			}
		}
		n, err := br.stream.Read(b)
		br.offset += int64(n)
		if err != nil && err != io.EOF {
			br.stream = nil
			br.datanodes.recordFailure(err)
			if n > 0 {
				return n, nil
			}
			continue
		}
		return n, err
	}
	err := br.datanodes.lastError()
	if err == nil {
		err = errors.New("No available datanodes for block.")
	}
	return 0, err
}