func New(f *os.File) (*DirectIO, error) {
	return NewSize(f, defaultBufSize)
}
New returns a new DirectIO writer with default buffer size.
package directio
import (
	"errors"
	"io"
	"os"
	"unsafe"
)
const (
	blockSize = 512
	defaultBufSize = 8192
)
func align(b []byte) int {
	return int(uintptr(unsafe.Pointer(&b[0])) & uintptr(blockSize-1))
}
func allocAlignedBuf(n int) ([]byte, error) {
	if n == 0 {
		return nil, errors.New("size is `0` can't allocate buffer")
	}
	buf := make([]byte, n+blockSize)
	a1 := align(buf)
	offset := 0
	if a1 != 0 {
		offset = blockSize - a1
	}
	buf = buf[offset : offset+n]
	if a1 == 0 {
		return buf, nil
	}
	a2 := align(buf)
	if a2 != 0 {
		return nil, errors.New("can't allocate aligned buffer")
	}
	return buf, nil
}
type DirectIO struct {
	f   *os.File
	buf []byte
	n   int
	err error
}
func NewSize(f *os.File, size int) (*DirectIO, error) {
	if err := checkDirectIO(f.Fd()); err != nil {
		return nil, err
	}
	if size%blockSize != 0 {
		size = size & -blockSize
	}
	if size < defaultBufSize {
		size = defaultBufSize
	}
	buf, err := allocAlignedBuf(size)
	if err != nil {
		return nil, err
	}
	return &DirectIO{
		buf: buf,
		f:   f,
	}, nil
}