func (f *File) Close() error {
	const op errors.Op = "file.Close"
	if f.closed {
		return f.errClosed(op)
	}
	f.closed = true
	if !f.writable {
		f.lastBlockIndex = -1
		f.lastBlockBytes = nil
		if err := f.bu.Close(); err != nil {
			return errors.E(op, err)
		}
		return nil
	}
	_, err := f.client.Put(f.name, f.data)
	f.data = nil  
	return err
}
Close implements upspin.File.
package main
import (
	"upspin.io/errors"
	"upspin.io/upspin"
)
var maxInt = int64(^uint(0) >> 1)
type File struct {
	name     upspin.PathName  
	offset   int64            
	writable bool             
	closed   bool             
	config upspin.Config
	entry  *upspin.DirEntry
	size   int64
	bu     upspin.BlockUnpacker
	lastBlockIndex int
	lastBlockBytes []byte
	client upspin.Client  
	data   []byte         
}
var _ upspin.File = (*File)(nil)
func Writable(client upspin.Client, name upspin.PathName, truncate bool) (*File, error) {
	var data []byte
	if !truncate {
		var err error
		data, err = client.Get(name)
		if err != nil {
			return nil, err
		}
	}
	return &File{
		client:   client,
		name:     name,
		writable: true,
		data:     data,
	}, nil
}
func (f *File) Name() upspin.PathName {
	return f.name
}
func (f *File) Read(b []byte) (n int, err error) {
	panic("not implemented")
}
func (f *File) ReadAt(b []byte, off int64) (n int, err error) {
	panic("not implemented")
}
func (f *File) Seek(offset int64, whence int) (ret int64, err error) {
	panic("not implemented")
}
func (f *File) Write(b []byte) (n int, err error) {
	panic("not implemented")
}
func (f *File) WriteAt(b []byte, off int64) (n int, err error) {
	const op errors.Op = "file.WriteAt"
	return f.writeAt(op, b, off)
}
func (f *File) writeAt(op errors.Op, b []byte, off int64) (n int, err error) {
	if f.closed {
		return 0, f.errClosed(op)
	}
	if !f.writable {
		return 0, errors.E(op, errors.Invalid, f.name, "not open for write")
	}
	if off < 0 {
		return 0, errors.E(op, errors.Invalid, f.name, "negative offset")
	}
	end := off + int64(len(b))
	if end > maxInt {
		return 0, errors.E(op, errors.Invalid, f.name, "file too long")
	}
	if end > int64(cap(f.data)) {
		nLen := end * 3 / 2
		if nLen > maxInt {
			nLen = maxInt
		}
		ndata := make([]byte, len(f.data), nLen)
		copy(ndata, f.data)
		f.data = ndata
	}
	if end > int64(len(f.data)) {
		f.data = f.data[:end]
	}
	copy(f.data[off:], b)
	return len(b), nil
}