emfs/file.go
2019-09-15 15:50:14 +04:30

142 lines
2.8 KiB
Go

package emfs
import (
"os"
"path/filepath"
"gitea.com/anotherGo/amutex"
"github.com/phayes/permbits"
)
type File struct {
amutex.Mutex
osFile *os.File
SyncImmediately bool
givenPath string
flags *[]FlagForOpen
isOpen bool
}
func NewFile(path ...string) (f *File) {
f.SetPath(path...)
return
}
func (file *File) Std() *os.File {
return file.osFile
}
func (file *File) Create(ex bool) error {
if file.IsOpen() {
return ErrIsOpen
}
defer file.Close()
if ex {
return file.Open(Cr)
} else {
return file.Open(Crx)
}
}
func (file *File) SetPath(path ...string) {
file.Close()
file.givenPath = filepath.Join(path...)
}
func (file *File) IsOpen() bool {
return file.isOpen
}
func (file *File) Remove(clse bool) error {
if file.IsOpen() && clse == false {
return ErrIsOpen
}
file.Close()
return os.Remove(file.GivenPath())
}
func (file *File) Open(flags ...FlagForOpen) error {
file.Close()
var flag FlagForOpen
for _, f := range flags {
flag |= f
}
if flag == 0 {
flag = DefaultFlag
}
var e error
file.osFile, e = os.OpenFile(file.givenPath, int(flag), os.FileMode(DefaultMode))
if e == nil {
file.isOpen = true
}
return e
}
func (file *File) OpenSync(flags ...FlagForOpen) error {
if len(flags) > 0 {
flags[0] |= Sync
return file.Open(flags...)
} else {
return file.Open(DefaultFlag, Sync)
}
}
func (file *File) Read(b []byte) (int, error) {
if file.IsOpen() == false {
file.Open(Rd)
defer file.Close()
}
return file.osFile.Read(b)
}
func (file *File) Write(b []byte, off int64) (int, error) {
if file.IsOpen() == false {
file.Open(Wr)
defer file.Close()
}
w, e := file.osFile.Write(b)
if e == nil && file.SyncImmediately {
e = file.Sync()
}
return w, e
}
func (file *File) Close() error {
e := file.osFile.Close()
file.SyncImmediately = false
file.osFile = nil
file.isOpen = false
file.UnlockAll()
file.RUnlockAll()
return e
}
func (file *File) Seek(off int64, w Whence) (int64, error) {
off, e := file.osFile.Seek(off, int(w))
return off, e
}
func (file *File) GivenPath() string {
return file.givenPath
}
func (file *File) AbsPath() string {
abs, _ := filepath.Abs(file.GivenPath())
return abs
}
func (file *File) Stat() (os.FileInfo, error) {
if file.IsOpen() {
return file.osFile.Stat()
} else {
return os.Stat(file.GivenPath())
}
}
func (file *File) Sync() error {
return file.osFile.Sync()
}
func (file *File) Truncate(size int64) error {
if file.IsOpen() == false {
file.Open(Tr)
defer file.Close()
}
e := file.osFile.Truncate(size)
if e == nil && file.SyncImmediately {
e = file.Sync()
}
return e
}
func (file *File) ChangeMode(mode permbits.PermissionBits) error {
return file.osFile.Chmod(os.FileMode(mode))
}
func (file *File) ChangeOwn(uid, gid int) error {
return file.osFile.Chown(uid, gid)
}