diff --git a/g/os/gfile/gfile_contents.go b/g/os/gfile/gfile_contents.go index 87738a114..716ee85f8 100644 --- a/g/os/gfile/gfile_contents.go +++ b/g/os/gfile/gfile_contents.go @@ -7,6 +7,7 @@ package gfile import ( + "gitee.com/johng/gf/g/os/gfpool" "io" "io/ioutil" "os" @@ -15,8 +16,8 @@ import ( const ( // 方法中涉及到读取的时候的缓冲大小 gREAD_BUFFER = 1024 - // 方法中涉及到文件指针池的默认缓存时间(秒) - gFILE_POOL_EXPIRE = 60 + // 方法中涉及到文件指针池的默认缓存时间(毫秒) + gFILE_POOL_EXPIRE = 60000 ) // (文本)读取文件内容 @@ -43,7 +44,7 @@ func putContents(path string, data []byte, flag int, perm int) error { } } // 创建/打开文件 - f, err := OpenWithFlagPerm(path, flag, perm) + f, err := gfpool.Open(path, flag, os.FileMode(perm), gFILE_POOL_EXPIRE) if err != nil { return err } @@ -82,11 +83,11 @@ func PutBinContentsAppend(path string, content []byte) error { } // 获得文件内容下一个指定字节的位置 -func GetNextCharOffset(file *os.File, char byte, start int64) int64 { +func GetNextCharOffset(reader io.ReaderAt, char byte, start int64) int64 { buffer := make([]byte, gREAD_BUFFER) offset := start for { - if n, err := file.ReadAt(buffer, offset); n > 0 { + if n, err := reader.ReadAt(buffer, offset); n > 0 { for i := 0; i < n; i++ { if buffer[i] == char { return int64(i) + offset @@ -102,7 +103,7 @@ func GetNextCharOffset(file *os.File, char byte, start int64) int64 { // 获得文件内容下一个指定字节的位置 func GetNextCharOffsetByPath(path string, char byte, start int64) int64 { - if f, err := OpenWithFlagPerm(path, os.O_RDONLY, gDEFAULT_PERM); err == nil { + if f, err := gfpool.Open(path, os.O_RDONLY, gDEFAULT_PERM, gFILE_POOL_EXPIRE); err == nil { defer f.Close() return GetNextCharOffset(f, char, start) } else { @@ -112,16 +113,16 @@ func GetNextCharOffsetByPath(path string, char byte, start int64) int64 { } // 获得文件内容直到下一个指定字节的位置(返回值包含该位置字符内容) -func GetBinContentsTilChar(file *os.File, char byte, start int64) ([]byte, int64) { - if offset := GetNextCharOffset(file, char, start); offset != -1 { - return GetBinContentsByTwoOffsets(file, start, offset + 1), offset +func GetBinContentsTilChar(reader io.ReaderAt, char byte, start int64) ([]byte, int64) { + if offset := GetNextCharOffset(reader, char, start); offset != -1 { + return GetBinContentsByTwoOffsets(reader, start, offset + 1), offset } return nil, -1 } // 获得文件内容直到下一个指定字节的位置(返回值包含该位置字符内容) func GetBinContentsTilCharByPath(path string, char byte, start int64) ([]byte, int64) { - if f, err := OpenWithFlagPerm(path, os.O_RDONLY, gDEFAULT_PERM); err == nil { + if f, err := gfpool.Open(path, os.O_RDONLY, gDEFAULT_PERM, gFILE_POOL_EXPIRE); err == nil { defer f.Close() return GetBinContentsTilChar(f, char, start) } else { @@ -131,9 +132,9 @@ func GetBinContentsTilCharByPath(path string, char byte, start int64) ([]byte, i } // 获得文件内容中两个offset之间的内容 [start, end) -func GetBinContentsByTwoOffsets(file *os.File, start int64, end int64) []byte { +func GetBinContentsByTwoOffsets(reader io.ReaderAt, start int64, end int64) []byte { buffer := make([]byte, end - start) - if _, err := file.ReadAt(buffer, start); err != nil { + if _, err := reader.ReadAt(buffer, start); err != nil { return nil } return buffer @@ -141,7 +142,7 @@ 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 := OpenWithFlagPerm(path, os.O_RDONLY, gDEFAULT_PERM); err == nil { + if f, err := gfpool.Open(path, os.O_RDONLY, gDEFAULT_PERM, gFILE_POOL_EXPIRE); err == nil { defer f.Close() return GetBinContentsByTwoOffsets(f, start, end) } else { diff --git a/g/os/gfpool/gfpool.go b/g/os/gfpool/gfpool.go index 9e9b73c9f..95a8d7e8c 100644 --- a/g/os/gfpool/gfpool.go +++ b/g/os/gfpool/gfpool.go @@ -28,7 +28,7 @@ type Pool struct { // 文件指针池指针 type File struct { - os.File // 底层文件指针 + *os.File // 底层文件指针 mu sync.RWMutex // 互斥锁 pool *Pool // 所属池 poolid int // 所属池ID,如果池ID不同表示池已经重建,那么该文件指针也应当销毁,不能重新丢到原有的池中 @@ -81,8 +81,8 @@ func newFilePool(p *Pool, path string, flag int, perm os.FileMode, expire int) * if err != nil { return nil, err } - return &File{ - File : *file, + return &File { + File : file, pool : p, poolid : p.id.Val(), flag : flag, @@ -108,7 +108,7 @@ func (p *Pool) File() (*File, error) { if file, err := os.OpenFile(f.path, f.flag, f.perm); err != nil { return nil, err } else { - f.File = *file + f.File = file if stat, err = f.Stat(); err != nil { return nil, err } @@ -127,7 +127,9 @@ func (p *Pool) File() (*File, error) { return nil, err } } else { - f.Seek(0, 0) + if _, err := f.Seek(0, 0); err != nil { + return nil, err + } } if !p.inited.Set(true) { gfsnotify.Add(f.path, func(event *gfsnotify.Event) { diff --git a/g/os/gfpool/gfpool_test.go b/g/os/gfpool/gfpool_test.go index beef6771f..179705c50 100644 --- a/g/os/gfpool/gfpool_test.go +++ b/g/os/gfpool/gfpool_test.go @@ -5,17 +5,44 @@ import ( "os" ) -func Benchmark_os_Open_Close(b *testing.B) { +func Benchmark_os_Open_Close_ALLFlags(b *testing.B) { for i := 0; i < b.N; i++ { - f, _ := os.OpenFile("/tmp/bench-test", os.O_RDWR|os.O_CREATE|os.O_TRUNC|os.O_APPEND, 0766) + f, _ := os.OpenFile("/tmp/bench-test", os.O_RDWR|os.O_CREATE|os.O_TRUNC|os.O_APPEND, 0666) f.Close() } } -func Benchmark_gfpool_Open_Close(b *testing.B) { +func Benchmark_gfpool_Open_Close_ALLFlags(b *testing.B) { for i := 0; i < b.N; i++ { - f, _ := Open("/tmp/bench-test", os.O_RDWR|os.O_CREATE|os.O_TRUNC|os.O_APPEND, 0766) + f, _ := Open("/tmp/bench-test", os.O_RDWR|os.O_CREATE|os.O_TRUNC|os.O_APPEND, 0666) f.Close() } } +func Benchmark_os_Open_Close_RDWR(b *testing.B) { + for i := 0; i < b.N; i++ { + f, _ := os.OpenFile("/tmp/bench-test", os.O_RDWR, 0666) + f.Close() + } +} + +func Benchmark_gfpool_Open_Close_RDWR(b *testing.B) { + for i := 0; i < b.N; i++ { + f, _ := Open("/tmp/bench-test", os.O_RDWR, 0666) + f.Close() + } +} + +func Benchmark_os_Open_Close_RDONLY(b *testing.B) { + for i := 0; i < b.N; i++ { + f, _ := os.OpenFile("/tmp/bench-test", os.O_RDONLY, 0666) + f.Close() + } +} + +func Benchmark_gfpool_Open_Close_RDONLY(b *testing.B) { + for i := 0; i < b.N; i++ { + f, _ := Open("/tmp/bench-test", os.O_RDONLY, 0666) + f.Close() + } +} \ No newline at end of file diff --git a/geg/other/test.go b/geg/other/test.go index 9a28077b6..f8bfab37a 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -2,15 +2,18 @@ package main import ( "fmt" + "gitee.com/johng/gf/g/os/gfpool" "os" "time" ) func main() { for { - stat, err := os.Stat("/home/john/temp/log") + f, err := gfpool.Open("/home/john/temp/log", os.O_RDWR, 0666) fmt.Println(err) - fmt.Println(stat.Size()) + _, err = f.WriteString("123") + fmt.Println(err) + //f.Close() time.Sleep(time.Second) } } \ No newline at end of file