118 lines
2.6 KiB
Go
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)
|
|
}
|