func (f *File) Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error {
	if f.IsArchive() || f.fs.readonly {
		return fuse.EPERM
	}
	f.fs.Lock()
	defer f.fs.Unlock()
	olen := uint64(len(f.Data))    
	wlen := uint64(len(req.Data))  
	off := uint64(req.Offset)      
	lim := off + wlen              
	if olen != f.Attrs.Size {
		msg := "bad size match: %d vs %d"
		logger.Error(msg, olen, f.Attrs.Size)
	}
	if lim > olen {
		buf := make([]byte, lim)
		var to uint64
		if off < olen {
			to = off
		} else {
			to = olen
		}
		copy(buf[0:to], f.Data[0:to])
		f.Data = buf
		f.Attrs.Size = lim
		f.Attrs.Blocks = Blocks(f.Attrs.Size)
		f.fs.nbytes += lim - olen
	}
	copy(f.Data[off:lim], req.Data[:])
	resp.Size = int(wlen)
	f.dirty = true
	logger.Debug("wrote %d bytes offset by %d to file %d", wlen, off, f.ID)
	return nil
}
Release the handle to the file. No associated documentation.

https://godoc.org/bazil.org/fuse/fs#HandleReleaser
func (f *File) Release(ctx context.Context, req *fuse.ReleaseRequest) error {
logger.Debug("release handle on file %d", f.ID)
return nil
}
Write requests to write data into the handle at the given offset.
Store the amount of data written in resp.Size.

There is a writeback page cache in the kernel that normally submits only
page-aligned writes spanning one or more pages. However, you should not
rely on this. To see individual requests as submitted by the file system
clients, set OpenDirectIO.

Writes that grow the file are expected to update the file size (as seen
through Attr). Note that file size changes are communicated also through
Setattr.

https://godoc.org/bazil.org/fuse/fs#HandleWriter
package memfs
import (
	"os"
	"time"
	"bazil.org/fuse"
	"golang.org/x/net/context"
)
type File struct {
	Node
	Data  []byte  
	dirty bool    
}
func (f *File) Init(name string, mode os.FileMode, parent *Dir, memfs *FileSystem) {
	f.Node.Init(name, mode, parent, memfs)
	f.Data = make([]byte, 0, 0)
}
func (f *File) GetNode() *Node {
	return &f.Node
}
func (f *File) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error {
	if f.IsArchive() || f.fs.readonly {
		return fuse.EPERM
	}
	if req.Valid.Size() {
		f.fs.Lock()  
		f.Attrs.Size = req.Size
		f.Attrs.Blocks = Blocks(f.Attrs.Size)
		f.Data = f.Data[:req.Size]  
		logger.Debug("truncate size from %d to %d on file %d", f.Attrs.Size, req.Size, f.ID)
		f.fs.Unlock()  
	}
	return f.Node.Setattr(ctx, req, resp)
}
func (f *File) Fsync(ctx context.Context, req *fuse.FsyncRequest) error {
	f.fs.Lock()
	defer f.fs.Unlock()
	logger.Debug("fsync on file %d", f.ID)
	return nil
}
func (f *File) Flush(ctx context.Context, req *fuse.FlushRequest) error {
	logger.Info("flush file %d (dirty: %t, contains %d bytes with size %d)", f.ID, f.dirty, len(f.Data), f.Attrs.Size)
	if f.IsArchive() || f.fs.readonly {
		return fuse.EPERM
	}
	f.fs.Lock()
	defer f.fs.Unlock()
	if !f.dirty {
		return nil
	}
	f.Attrs.Atime = time.Now()
	f.Attrs.Mtime = f.Attrs.Atime
	f.dirty = false
	return nil
}
func (f *File) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
	f.fs.Lock()
	defer f.fs.Unlock()
	to := uint64(req.Offset) + uint64(req.Size)
	if to > f.Attrs.Size {
		to = f.Attrs.Size
	}
	f.Attrs.Atime = time.Now()
	resp.Data = f.Data[req.Offset:to]
	logger.Debug("read %d bytes from offset %d in file %d", req.Size, req.Offset, f.ID)
	return nil
}