mirror of
https://gitee.com/johng/gf
synced 2026-07-04 21:03:13 +08:00
merge master
This commit is contained in:
6
TODO.MD
6
TODO.MD
@ -40,9 +40,9 @@
|
||||
- https://github.com/namreg/godown
|
||||
- https://github.com/Masterminds/sprig
|
||||
1. gform参考 https://gohouse.github.io/gorose/dist/index.html 进行改进
|
||||
1. 模板引擎增加对象的支持(参考https://segmentfault.com/q/1010000016829214);
|
||||
|
||||
|
||||
1. 模板引擎增加对对象的支持(参考https://segmentfault.com/q/1010000016829214);
|
||||
1. 由于系统对inotify实例数量(`fs.inotify.max_user_instances`)以及队列大小(`fs.inotify.max_user_watches`)有限制,需要改进`gfsnotify`;
|
||||
1. 改进gfpool在文件指针变化时的更新;
|
||||
|
||||
|
||||
# DONE
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
package gfile
|
||||
|
||||
import (
|
||||
"gitee.com/johng/gf/g/os/gfpool"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@ -35,7 +34,7 @@ func GetBinContents(path string) []byte {
|
||||
}
|
||||
|
||||
// 写入文件内容
|
||||
func putContents(path string, data []byte, flag int, perm os.FileMode) error {
|
||||
func putContents(path string, data []byte, flag int, perm int) error {
|
||||
// 支持目录递归创建
|
||||
dir := Dir(path)
|
||||
if !Exists(dir) {
|
||||
@ -43,8 +42,8 @@ func putContents(path string, data []byte, flag int, perm os.FileMode) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// 创建/打开文件,使用文件指针池,默认60秒
|
||||
f, err := gfpool.OpenFile(path, flag, perm, gFILE_POOL_EXPIRE*1000)
|
||||
// 创建/打开文件
|
||||
f, err := OpenWithFlagPerm(path, flag, perm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -103,11 +102,11 @@ func GetNextCharOffset(file *os.File, char byte, start int64) int64 {
|
||||
|
||||
// 获得文件内容下一个指定字节的位置
|
||||
func GetNextCharOffsetByPath(path string, char byte, start int64) int64 {
|
||||
if f, err := gfpool.Open(path, os.O_RDONLY, gDEFAULT_PERM, gFILE_POOL_EXPIRE*1000); err == nil {
|
||||
if f, err := OpenWithFlagPerm(path, os.O_RDONLY, gDEFAULT_PERM); err == nil {
|
||||
defer f.Close()
|
||||
return GetNextCharOffset(&f.File, char, start)
|
||||
return GetNextCharOffset(f, char, start)
|
||||
} else {
|
||||
// panic(err)
|
||||
panic(err)
|
||||
}
|
||||
return -1
|
||||
}
|
||||
@ -122,11 +121,11 @@ func GetBinContentsTilChar(file *os.File, char byte, start int64) ([]byte, int64
|
||||
|
||||
// 获得文件内容直到下一个指定字节的位置(返回值包含该位置字符内容)
|
||||
func GetBinContentsTilCharByPath(path string, char byte, start int64) ([]byte, int64) {
|
||||
if f, err := gfpool.Open(path, os.O_RDONLY, gDEFAULT_PERM, gFILE_POOL_EXPIRE*1000); err == nil {
|
||||
if f, err := OpenWithFlagPerm(path, os.O_RDONLY, gDEFAULT_PERM); err == nil {
|
||||
defer f.Close()
|
||||
return GetBinContentsTilChar(&f.File, char, start)
|
||||
return GetBinContentsTilChar(f, char, start)
|
||||
} else {
|
||||
// panic(err)
|
||||
panic(err)
|
||||
}
|
||||
return nil, -1
|
||||
}
|
||||
@ -142,11 +141,11 @@ func GetBinContentsByTwoOffsets(file *os.File, start int64, end int64) []byte {
|
||||
|
||||
// 获得文件内容中两个offset之间的内容 [start, end)
|
||||
func GetBinContentsByTwoOffsetsByPath(path string, start int64, end int64) []byte {
|
||||
if f, err := gfpool.Open(path, os.O_RDONLY, gDEFAULT_PERM, gFILE_POOL_EXPIRE*1000); err == nil {
|
||||
if f, err := OpenWithFlagPerm(path, os.O_RDONLY, gDEFAULT_PERM); err == nil {
|
||||
defer f.Close()
|
||||
return GetBinContentsByTwoOffsets(&f.File, start, end)
|
||||
return GetBinContentsByTwoOffsets(f, start, end)
|
||||
} else {
|
||||
// panic(err)
|
||||
panic(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -42,24 +42,32 @@ type File struct {
|
||||
var pools = gmap.NewStringInterfaceMap()
|
||||
|
||||
// 获得文件对象,并自动创建指针池(过期时间单位:毫秒)
|
||||
func Open(path string, flag int, perm os.FileMode, expire...int) (*File, error) {
|
||||
func Open(path string, flag int, perm os.FileMode, expire...int) (file *File, err error) {
|
||||
fpExpire := 0
|
||||
if len(expire) > 0 {
|
||||
fpExpire = expire[0]
|
||||
}
|
||||
pool := pools.GetOrSetFuncLock(fmt.Sprintf("%s&%d&%d&%d", path, flag, expire, perm), func() interface{} {
|
||||
return New(path, flag, perm, fpExpire)
|
||||
if p, e := New(path, flag, perm, fpExpire); e == nil {
|
||||
return p
|
||||
} else {
|
||||
err = e
|
||||
}
|
||||
return nil
|
||||
}).(*Pool)
|
||||
if pool == nil {
|
||||
return nil, err
|
||||
}
|
||||
return pool.File()
|
||||
}
|
||||
|
||||
func OpenFile(path string, flag int, perm os.FileMode, expire...int) (*File, error) {
|
||||
func OpenFile(path string, flag int, perm os.FileMode, expire...int) (file *File, err error) {
|
||||
return Open(path, flag, perm, expire...)
|
||||
}
|
||||
|
||||
// 创建一个文件指针池,expire = 0表示不过期,expire < 0表示使用完立即回收,expire > 0表示超时回收,默认值为0不过期
|
||||
// 过期时间单位:毫秒
|
||||
func New(path string, flag int, perm os.FileMode, expire...int) *Pool {
|
||||
func New(path string, flag int, perm os.FileMode, expire...int) (*Pool, error) {
|
||||
fpExpire := 0
|
||||
if len(expire) > 0 {
|
||||
fpExpire = expire[0]
|
||||
@ -74,9 +82,9 @@ func New(path string, flag int, perm os.FileMode, expire...int) *Pool {
|
||||
if watcher, err := fsnotify.NewWatcher(); err == nil {
|
||||
p.watcher = watcher
|
||||
} else {
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
return p
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// 创建文件指针池
|
||||
|
||||
@ -8,19 +8,18 @@
|
||||
package glog
|
||||
|
||||
import (
|
||||
"os"
|
||||
"io"
|
||||
"time"
|
||||
"fmt"
|
||||
"strings"
|
||||
"runtime"
|
||||
"gitee.com/johng/gf/g/os/gfile"
|
||||
"gitee.com/johng/gf/g/util/gregex"
|
||||
"gitee.com/johng/gf/g/container/gtype"
|
||||
"gitee.com/johng/gf/g/os/gfile"
|
||||
"gitee.com/johng/gf/g/os/gmlock"
|
||||
"gitee.com/johng/gf/g/os/gfpool"
|
||||
"sync"
|
||||
"gitee.com/johng/gf/g/os/gtime"
|
||||
"gitee.com/johng/gf/g/util/gregex"
|
||||
"io"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Logger struct {
|
||||
@ -128,14 +127,14 @@ func (l *Logger) GetWriter() io.Writer {
|
||||
}
|
||||
|
||||
// 获取默认的文件IO
|
||||
func (l *Logger) getFilePointer() *gfpool.File {
|
||||
func (l *Logger) getFilePointer() *os.File {
|
||||
if path := l.path.Val(); path != "" {
|
||||
// 文件名称中使用"{}"包含的内容使用gtime格式化
|
||||
file, _ := gregex.ReplaceStringFunc(`{.+?}`, l.file.Val(), func(s string) string {
|
||||
return gtime.Now().Format(strings.Trim(s, "{}"))
|
||||
})
|
||||
fpath := path + gfile.Separator + file
|
||||
if fp, err := gfpool.Open(fpath, gDEFAULT_FILE_POOL_FLAGS, 0666); err == nil {
|
||||
if fp, err := gfile.OpenWithFlagPerm(fpath, gDEFAULT_FILE_POOL_FLAGS, 0666); err == nil {
|
||||
return fp
|
||||
} else {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
@ -249,20 +248,20 @@ func (l *Logger) GetBacktrace(skip...int) string {
|
||||
from := 0
|
||||
// 首先定位业务文件开始位置
|
||||
for i := 0; i < 10; i++ {
|
||||
if _, cfile, _, ok := runtime.Caller(i); ok {
|
||||
if !gregex.IsMatchString("/g/os/glog/glog.+$", cfile) {
|
||||
if _, file, _, ok := runtime.Caller(i); ok {
|
||||
if !gregex.IsMatchString("/g/os/glog/glog.+$", file) {
|
||||
from = i
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// 从业务文件开始位置根据自定义的skip开始backtrace
|
||||
goroot := runtime.GOROOT()
|
||||
goRoot := runtime.GOROOT()
|
||||
for i := from + customSkip + l.btSkip.Val(); i < 10000; i++ {
|
||||
if _, cfile, cline, ok := runtime.Caller(i); ok && cfile != "" {
|
||||
if _, file, cline, ok := runtime.Caller(i); ok && file != "" {
|
||||
// 不打印出go源码路径及glog包文件路径,日志打印必须从业务源码文件开始,且从glog包文件开始检索
|
||||
if (goroot == "" || !gregex.IsMatchString("^" + goroot, cfile)) && !gregex.IsMatchString(`<autogenerated>`, cfile) {
|
||||
backtrace += fmt.Sprintf(`%d. %s:%d%s`, index, cfile, cline, ln)
|
||||
if (goRoot == "" || !gregex.IsMatchString("^" + goRoot, file)) && !gregex.IsMatchString(`<autogenerated>`, file) {
|
||||
backtrace += fmt.Sprintf(`%d. %s:%d%s`, index, file, cline, ln)
|
||||
index++
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -1,21 +1,17 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"log"
|
||||
"os"
|
||||
"fmt"
|
||||
"gitee.com/johng/gf/g/os/gtime"
|
||||
"gitee.com/johng/gf/third/github.com/fsnotify/fsnotify"
|
||||
)
|
||||
|
||||
type Person string
|
||||
|
||||
func (p Person) Label() string {
|
||||
return "This is " + string(p)
|
||||
}
|
||||
|
||||
func main() {
|
||||
tmpl, err := template.New("").Parse(`{{sum 1 2 3}}`)
|
||||
if err != nil {
|
||||
log.Fatalf("Parse: %v", err)
|
||||
if w, err := fsnotify.NewWatcher(); err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
fmt.Println(gtime.Now().String())
|
||||
w.Add("/tmp/test")
|
||||
}
|
||||
tmpl.Execute(os.Stdout, nil)
|
||||
|
||||
}
|
||||
@ -1,12 +1,11 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gitee.com/johng/gf/g/util/gregex"
|
||||
"gitee.com/johng/gf/g/container/garray"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := `[0-9][0-9]/Jan/[0-9][0-9][0-9][0-9]:[0-9][0-9]:[0-9][0-9]:[0-9][0-9] \+[0-9][0-9][0-9][0-9]`
|
||||
s,_ = gregex.ReplaceString(`[A-Za-z]`, `[A-Za-z]`, s)
|
||||
fmt.Println(s)
|
||||
a := garray.NewSortedIntArray(0)
|
||||
a.Add(1)
|
||||
a.Remove(0)
|
||||
}
|
||||
Reference in New Issue
Block a user