改进gfile文件内容操作为使用gfpool

This commit is contained in:
john
2018-11-08 14:00:28 +08:00
parent f1714b245f
commit 59318ca184
4 changed files with 57 additions and 24 deletions

View File

@ -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 {

View File

@ -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) {

View File

@ -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()
}
}

View File

@ -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)
}
}