quickshare/server/libs/fsutil/fsutil.go
hekk 61a1c93f0f !1 Merge back to master
Merge pull request !1 from dev branch
2018-05-27 21:32:55 +08:00

118 lines
2.6 KiB
Go

package fsutil
import (
"errors"
"io"
"os"
)
import (
"quickshare/server/libs/errutil"
"quickshare/server/libs/fileidx"
"quickshare/server/libs/qtube"
)
type FsUtil interface {
CreateFile(fullPath string) error
CopyChunkN(fullPath string, chunk io.Reader, start int64, length int64) bool
DelFile(fullPath string) bool
Open(fullPath string) (qtube.ReadSeekCloser, error)
MkdirAll(path string, mode os.FileMode) bool
Readdir(dirName string, n int) ([]*fileidx.FileInfo, error)
}
func NewSimpleFs(errUtil errutil.ErrUtil) FsUtil {
return &SimpleFs{
Err: errUtil,
}
}
type SimpleFs struct {
Err errutil.ErrUtil
}
var (
ErrExists = errors.New("file exists")
ErrUnknown = errors.New("unknown error")
)
func (sfs *SimpleFs) CreateFile(fullPath string) error {
flag := os.O_CREATE | os.O_EXCL | os.O_RDONLY
perm := os.FileMode(0644)
newFile, err := os.OpenFile(fullPath, flag, perm)
defer newFile.Close()
if err == nil {
return nil
} else if os.IsExist(err) {
return ErrExists
} else {
return ErrUnknown
}
}
func (sfs *SimpleFs) CopyChunkN(fullPath string, chunk io.Reader, start int64, length int64) bool {
flag := os.O_WRONLY
perm := os.FileMode(0644)
file, openErr := os.OpenFile(fullPath, flag, perm)
defer file.Close()
if sfs.Err.IsErr(openErr) {
return false
}
if _, err := file.Seek(start, io.SeekStart); sfs.Err.IsErr(err) {
return false
}
if _, err := io.CopyN(file, chunk, length); sfs.Err.IsErr(err) && err != io.EOF {
return false
}
return true
}
func (sfs *SimpleFs) DelFile(fullPath string) bool {
return !sfs.Err.IsErr(os.Remove(fullPath))
}
func (sfs *SimpleFs) MkdirAll(path string, mode os.FileMode) bool {
err := os.MkdirAll(path, mode)
return !sfs.Err.IsErr(err)
}
// TODO: not support read from last seek position
func (sfs *SimpleFs) Readdir(dirName string, n int) ([]*fileidx.FileInfo, error) {
dir, openErr := os.Open(dirName)
defer dir.Close()
if sfs.Err.IsErr(openErr) {
return []*fileidx.FileInfo{}, openErr
}
osFileInfos, readErr := dir.Readdir(n)
if sfs.Err.IsErr(readErr) && readErr != io.EOF {
return []*fileidx.FileInfo{}, readErr
}
fileInfos := make([]*fileidx.FileInfo, 0)
for _, osFileInfo := range osFileInfos {
if osFileInfo.Mode().IsRegular() {
fileInfos = append(
fileInfos,
&fileidx.FileInfo{
ModTime: osFileInfo.ModTime().UnixNano(),
PathLocal: osFileInfo.Name(),
Uploaded: osFileInfo.Size(),
},
)
}
}
return fileInfos, readErr
}
// the associated file descriptor has mode O_RDONLY as using os.Open
func (sfs *SimpleFs) Open(fullPath string) (qtube.ReadSeekCloser, error) {
return os.Open(fullPath)
}