update archive method
parent
1632256ded
commit
9adabd6723
@ -0,0 +1 @@
|
|||||||
|
package starlog
|
@ -0,0 +1,44 @@
|
|||||||
|
package staros
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ERR_ALREADY_LOCKED = errors.New("ALREADY LOCKED")
|
||||||
|
var ERR_TIMEOUT = errors.New("TIME OUT")
|
||||||
|
|
||||||
|
func NewFileLock(filepath string) FileLock {
|
||||||
|
return FileLock{
|
||||||
|
filepath: filepath,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测文件/文件夹是否存在
|
||||||
|
func Exists(path string) bool {
|
||||||
|
_, err := os.Stat(path)
|
||||||
|
if err != nil && os.IsNotExist(err) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsFile 返回给定文件地址是否是一个文件,
|
||||||
|
//True为是一个文件,False为不是文件或路径无效
|
||||||
|
func IsFile(fpath string) bool {
|
||||||
|
s, err := os.Stat(fpath)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return !s.IsDir()
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsFolder 返回给定文件地址是否是一个文件夹,
|
||||||
|
//True为是一个文件夹,False为不是文件夹或路径无效
|
||||||
|
func IsFolder(fpath string) bool {
|
||||||
|
s, err := os.Stat(fpath)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return s.IsDir()
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
//+build darwin
|
||||||
|
|
||||||
|
package staros
|
||||||
|
|
||||||
|
import (
|
||||||
|
"b612.me/stario"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FileLock struct {
|
||||||
|
fd int
|
||||||
|
filepath string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileLock) openFileForLock() error {
|
||||||
|
fd, err := syscall.Open(f.filepath, syscall.O_CREAT|syscall.O_RDONLY, 0600)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
f.filepath = f.filepath
|
||||||
|
f.fd = fd
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileLock) Lock(Exclusive bool) error {
|
||||||
|
var lockType int
|
||||||
|
if Exclusive {
|
||||||
|
lockType = syscall.LOCK_EX
|
||||||
|
} else {
|
||||||
|
lockType = syscall.LOCK_SH
|
||||||
|
}
|
||||||
|
if err := f.openFileForLock(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return syscall.Flock(f.fd, lockType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileLock) LockNoBlocking(Exclusive bool) error {
|
||||||
|
var lockType int
|
||||||
|
if Exclusive {
|
||||||
|
lockType = syscall.LOCK_EX
|
||||||
|
} else {
|
||||||
|
lockType = syscall.LOCK_SH
|
||||||
|
}
|
||||||
|
if err := f.openFileForLock(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err := syscall.Flock(f.fd, lockType|syscall.LOCK_NB)
|
||||||
|
if err != nil {
|
||||||
|
syscall.Close(f.fd)
|
||||||
|
if err == syscall.EWOULDBLOCK {
|
||||||
|
return ERR_ALREADY_LOCKED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileLock) Unlock() error {
|
||||||
|
err := syscall.Flock(f.fd, syscall.LOCK_UN)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return syscall.Close(f.fd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileLock) LockWithTimeout(tm time.Duration, Exclusive bool) error {
|
||||||
|
return stario.WaitUntilTimeout(tm, func(tmout chan struct{}) error {
|
||||||
|
err := f.Lock(Exclusive)
|
||||||
|
select {
|
||||||
|
case <-tmout:
|
||||||
|
f.Unlock()
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func timespecToTime(ts syscall.Timespec) time.Time {
|
||||||
|
return time.Unix(int64(ts.Sec), int64(ts.Nsec))
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFileCreationTime(fileinfo os.FileInfo) time.Time {
|
||||||
|
return timespecToTime(fileinfo.Sys().(*syscall.Stat_t).Ctimespec)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFileAccessTime(fileinfo os.FileInfo) time.Time {
|
||||||
|
return timespecToTime(fileinfo.Sys().(*syscall.Stat_t).Atimespec)
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
//+build linux
|
||||||
|
|
||||||
|
package staros
|
||||||
|
|
||||||
|
import (
|
||||||
|
"b612.me/stario"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FileLock struct {
|
||||||
|
fd int
|
||||||
|
filepath string
|
||||||
|
}
|
||||||
|
|
||||||
|
func timespecToTime(ts syscall.Timespec) time.Time {
|
||||||
|
return time.Unix(int64(ts.Sec), int64(ts.Nsec))
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFileCreationTime(fileinfo os.FileInfo) time.Time {
|
||||||
|
return timespecToTime(fileinfo.Sys().(*syscall.Stat_t).Ctim)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFileAccessTime(fileinfo os.FileInfo) time.Time {
|
||||||
|
return timespecToTime(fileinfo.Sys().(*syscall.Stat_t).Atim)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileLock) openFileForLock() error {
|
||||||
|
fd, err := syscall.Open(f.filepath, syscall.O_CREAT|syscall.O_RDONLY, 0600)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
f.filepath = f.filepath
|
||||||
|
f.fd = fd
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileLock) Lock(Exclusive bool) error {
|
||||||
|
var lockType int
|
||||||
|
if Exclusive {
|
||||||
|
lockType = syscall.LOCK_EX
|
||||||
|
} else {
|
||||||
|
lockType = syscall.LOCK_SH
|
||||||
|
}
|
||||||
|
if err := f.openFileForLock(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return syscall.Flock(f.fd, lockType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileLock) LockNoBlocking(Exclusive bool) error {
|
||||||
|
var lockType int
|
||||||
|
if Exclusive {
|
||||||
|
lockType = syscall.LOCK_EX
|
||||||
|
} else {
|
||||||
|
lockType = syscall.LOCK_SH
|
||||||
|
}
|
||||||
|
if err := f.openFileForLock(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err := syscall.Flock(f.fd, lockType|syscall.LOCK_NB)
|
||||||
|
if err != nil {
|
||||||
|
syscall.Close(f.fd)
|
||||||
|
if err == syscall.EWOULDBLOCK {
|
||||||
|
return ERR_ALREADY_LOCKED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileLock) Unlock() error {
|
||||||
|
err := syscall.Flock(f.fd, syscall.LOCK_UN)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return syscall.Close(f.fd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileLock) LockWithTimeout(tm time.Duration, Exclusive bool) error {
|
||||||
|
return stario.WaitUntilTimeout(tm, func(tmout chan struct{}) error {
|
||||||
|
err := f.Lock(Exclusive)
|
||||||
|
select {
|
||||||
|
case <-tmout:
|
||||||
|
f.Unlock()
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
}
|
@ -0,0 +1,123 @@
|
|||||||
|
// +build windows
|
||||||
|
|
||||||
|
package staros
|
||||||
|
|
||||||
|
import (
|
||||||
|
"b612.me/win32api"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FileLock struct {
|
||||||
|
filepath string
|
||||||
|
handle win32api.HANDLE
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFileCreationTime(fileinfo os.FileInfo) time.Time {
|
||||||
|
d := fileinfo.Sys().(*syscall.Win32FileAttributeData)
|
||||||
|
return time.Unix(0, d.CreationTime.Nanoseconds())
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFileAccessTime(fileinfo os.FileInfo) time.Time {
|
||||||
|
d := fileinfo.Sys().(*syscall.Win32FileAttributeData)
|
||||||
|
return time.Unix(0, d.LastAccessTime.Nanoseconds())
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetFileTimes(file *os.File, info os.FileInfo) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetFileTimesbyTime(file *os.File) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileLock) openFileForLock() error {
|
||||||
|
name, err := syscall.UTF16PtrFromString(f.filepath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
handle, err := syscall.CreateFile(
|
||||||
|
name,
|
||||||
|
syscall.GENERIC_READ,
|
||||||
|
syscall.FILE_SHARE_READ,
|
||||||
|
nil,
|
||||||
|
syscall.OPEN_ALWAYS,
|
||||||
|
syscall.FILE_FLAG_OVERLAPPED|0x00000080,
|
||||||
|
0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
f.handle = win32api.HANDLE(handle)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileLock) lockForTimeout(timeout time.Duration, lockType win32api.DWORD) error {
|
||||||
|
var err error
|
||||||
|
if err = f.openFileForLock(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
event, err := win32api.CreateEventW(nil, true, false, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
myEvent := &syscall.Overlapped{HEvent: syscall.Handle(event)}
|
||||||
|
defer syscall.CloseHandle(myEvent.HEvent)
|
||||||
|
_, err = win32api.LockFileEx(f.handle, lockType, 0, 1, 0, myEvent)
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err != syscall.ERROR_IO_PENDING {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
millis := uint32(syscall.INFINITE)
|
||||||
|
if timeout >= 0 {
|
||||||
|
millis = uint32(timeout.Nanoseconds() / 1000000)
|
||||||
|
}
|
||||||
|
s, err := syscall.WaitForSingleObject(myEvent.HEvent, millis)
|
||||||
|
switch s {
|
||||||
|
case syscall.WAIT_OBJECT_0:
|
||||||
|
// success!
|
||||||
|
return nil
|
||||||
|
case syscall.WAIT_TIMEOUT:
|
||||||
|
f.Unlock()
|
||||||
|
return ERR_TIMEOUT
|
||||||
|
default:
|
||||||
|
f.Unlock()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileLock) Lock(Exclusive bool) error {
|
||||||
|
var lockType win32api.DWORD
|
||||||
|
if Exclusive {
|
||||||
|
lockType = win32api.LOCKFILE_EXCLUSIVE_LOCK
|
||||||
|
} else {
|
||||||
|
lockType = 0
|
||||||
|
}
|
||||||
|
return f.lockForTimeout(0, lockType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileLock) LockWithTimeout(tm time.Duration, Exclusive bool) error {
|
||||||
|
var lockType win32api.DWORD
|
||||||
|
if Exclusive {
|
||||||
|
lockType = win32api.LOCKFILE_EXCLUSIVE_LOCK
|
||||||
|
} else {
|
||||||
|
lockType = 0
|
||||||
|
}
|
||||||
|
return f.lockForTimeout(tm, lockType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileLock) LockNoBlocking(Exclusive bool) error {
|
||||||
|
var lockType win32api.DWORD
|
||||||
|
if Exclusive {
|
||||||
|
lockType = win32api.LOCKFILE_EXCLUSIVE_LOCK
|
||||||
|
} else {
|
||||||
|
lockType = 0
|
||||||
|
}
|
||||||
|
return f.lockForTimeout(0, lockType|win32api.LOCKFILE_FAIL_IMMEDIATELY)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileLock) Unlock() error {
|
||||||
|
return syscall.Close(syscall.Handle(f.handle))
|
||||||
|
}
|
Loading…
Reference in New Issue